今日选择什么语言调用MindOpt对二次规划问题建模优化呢?

简介: MindOpt是达摩院决策智能实验室研究的一款优化求解器,能帮助做方案设计、生产方案优化、资源合理分配、辅助决策等。可以支持命令行、c、c++、java和python调用,目前求解算法实现了线性规划、混合整数线性规划、二次规划。

下文我们将讲述小编对线性规划的理解以及展示两个算例,和使用 MindOpt C 语言的 API 来建模以及求解 二次规划示例 中的问题。

(二次规划定义、算数例题都是与前文python语言的二次规划问题是一致的,已经阅读了前文可以忽略,直接点击目录进阶算例阅读建模优化代码。)


MindOpt Python、C、C++语言求解LP、MILP、QP问题系列


下载安装

用户可以点这里下载安装MindOpt优化求解器,免费的。找不到安装步骤点这里

(官网https://opt.aliyun.com有更多信息等着您哟!)


二次规划

在前文线性规划问题示例中,讲述到线性规划在我个人认为是在线性的目标和约束中,找出一个最优解。而本文的二次规划,是非线性规划中的一类。具体地说,是一个线性约束的、二次规划问题,就是优化(最小化或最大化)二次函数目标的问题。


关于优化的类别,有很多,比如MindOpt的案例广场的标签里面提到的问题标签,就列出了常见的数学规划的类型。其中关于变量、约束、目标这建模三要素,进行罗列:

  • 关于变量:取值有连续的,有整数的,还有更特殊的二进制(0或1)的,
  • 关于约束和目标:一般用变量的函数变换来表达,其中约束再增加它函数的取值范围。
  • 当函数是变量的线性关系时,比如x的1次方相加,我们称呼为线性约束、线性的目标。(如果变量也是连续的,这个就是线性规划问题啦。)
  • 当函数是变量的是二次关系的时候,比如函数中有 x的2次方项。我们称呼为二次约束,或二次目标。
  • 函数还会有凸函数和非凸函数,数学里面都代表不同的特性,大家可以再多去查阅材料。

image.png

本文主要讲 凸二次规划,Convex Quadratic Programming。

数学形式下的二次规划问题:

image.png

公式参考自MindOpt文档:https://solver.damo.alibaba.com/doc/html/model/qp/quadratic%20problem.html


案例

讲一个简单的例子,使用二次规划方法优化汽车轨迹,自动化驾驶车辆行驶在道路比较狭窄的路径上,还有其他障碍物阻碍的情况下,如果需要快速通过的话,我们需要暂时借用相邻车道通过,这个情况需要考虑自身车辆的情况、交通规则、保障远离障碍物距离的信息,然后找出一条通道。那么这个例子的解决办法是先考虑自身车辆的位置和周围障碍物,精确处理前一步可用车道,得到路径的边界,然后对路径边界进行优化(比如把车辆和障碍物之间的距离最大化,以允许车辆安全通过间隙)。

image.png

再比如,二次规划在机器人中应用,解决机械臂控制的问题。对于机器人来说,常常具备冗余关节,并且存在关节角度、角速度等限制条件,非常适合用二次规划方法来进行优化求解

image.png


数学算例

接下来我们举一个简单的数学算例,和如何用MindOpt优化求解器进行求解。

二次规划问题示例:

image.png


C语言+MindOpt代码实现

核心使用的几个APIs是:

MDO_CHECK_CALL(Mdo_createMdl(&model))
MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES))
MDO_CHECK_CALL(Mdo_addRow(model, 1.0, MDO_INFINITY, 4, row1_idx, row1_val, "c0"));
MDO_CHECK_CALL(Mdo_addRow(model, 1.0, 1.0,          3, row2_idx, row2_val, "c1"));
MDO_CHECK_CALL(Mdo_solveProb(model));
Mdo_displayResults(model);

#关于更多API的详细使用方式,请参考C 接口函数

下面是完整的例子,可复制存为MdoQoEx1.c文件。

#include <stdio.h>/*引入头文件*/#include "Mindopt.h"/* 检查返回码的宏 */#define MDO_CHECK_CALL(MDO_CALL)                                    \code = MDO_CALL;                                                \if (code != MDO_OKAY)                                           \{                                                               \Mdo_explainResult(model, code, str);                        \Mdo_freeMdl(&model);                                        \fprintf(stderr, "===================================\n");   \fprintf(stderr, "Error   : code <%d>\n", code);             \fprintf(stderr, "Reason  : %s\n", str);                     \fprintf(stderr, "===================================\n");   \return (int)code;                                           \}intmain(void)
{
/* 变量 */charstr[1024] = { "\0" };
MdoMdl*model=NULL;
MdoResultcode=MDO_OKAY;
MdoStatusstatus=MDO_UNKNOWN;
constintrow1_idx[] = { 0,   1,   2,   3   };
constdoublerow1_val[] = { 1.0, 1.0, 2.0, 3.0 };
constintrow2_idx[] = { 0,    2,   3   };
constdoublerow2_val[] = { 1.0, -1.0, 6.0 };
constintqo_col1[] =    {
0, 
1,   1,
2,
3    };
constintqo_col2[] =    {
0,
0,   1,
2,
3    };
constdoubleqo_values[] =    {
1.0,
0.5, 1.0,
1.0, 
1.0    };
/*------------------------------------------------------------------*//* Step 1. 创建模型并更改参数。               *//*------------------------------------------------------------------*//* 创建一个空模型。 */MDO_CHECK_CALL(Mdo_createMdl(&model));
/*------------------------------------------------------------------*//* Step 2. 输入模型。                                             *//*------------------------------------------------------------------*//* 改成最小化问题。 *//*通过 Mdo_setIntAttr() 将目标函数设置为 最小化 */MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
/* 添加变量。 *//*调用 Mdo_addCol() 来添加四个优化变量,定义其下界、上界、名称和类型*/MDO_CHECK_CALL(Mdo_addCol(model, 0.0, 10.0,         1.0, 0, NULL, NULL, "x0", MDO_YES));
MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x1", MDO_YES));
MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x2", MDO_YES));
MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x3", MDO_NO));
/* 添加约束。* 请注意,这里的非零元素是按行顺序输入的。*调用 Mdo_addRow() 来输入约束*/MDO_CHECK_CALL(Mdo_addRow(model, 1.0, MDO_INFINITY, 4, row1_idx, row1_val, "c0"));
MDO_CHECK_CALL(Mdo_addRow(model, 1.0, 1.0,          3, row2_idx, row2_val, "c1"));
/* 添加二次目标项。*/MDO_CHECK_CALL(Mdo_setQuadraticElements(模型, 5, qo_col1, qo_col2, qo_values)); 
/*------------------------------------------------------------------*//* Step 3. 解决问题并填充结果。               *//*------------------------------------------------------------------*//* 调用 Mdo_solveProb() 求解优化问题,并通过 Mdo_displayResults() 查看优化结果 */MDO_CHECK_CALL(Mdo_solveProb(model));
Mdo_displayResults(model);
/*------------------------------------------------------------------*//* Step 4. 释放模型。                                          *//*------------------------------------------------------------------*//* 调用 Mdo_freeMdl() 来释放内存 */Mdo_freeMdl(&model);
return (int)code;
}

MindOpt求解的结果

如何编译及运行MdoQoEx1.c文件

#运行方式与前文线性规划一致,只需要修改文件就好;把MdoQoEx1.c换成MdoQoEx1.c

windows系统本例是在Visual Studio上运行,版本为2019

c语言 windows系统运行mindopt.gif

/*linux和mac系统直接在命令行输入*/cd<MDOHOME>/<VERSION>/examples/Cmake-fMakefileall./MdoQoEx1

然后运行MdoQoEx1.c 文件后,得到求解的结果如下所示,/**/号里面是我添加的注释。

Modelsummary.           /*模型摘要*/-Num. variables     : 4-Num. constraints   : 2-Num. nonzeros      : 7-Boundrange        : [1.0e+00,1.0e+01]
-Objectiverange    : [1.0e+00,1.0e+00]
-Quad. obj. range   : [5.0e-01,1.0e+00]
-Matrixrange       : [1.0e+00,6.0e+00]
Presolverstarted.
Presolverterminated. Time : 0.000sInteriorpointmethodstarted.   /*内点法*/IterPrimObjDualObjPrimFeaDualFeaGapFeaMuTime0+5.21966603e+01-5.98089411e+017.3e-011.3e+002.1e+001.5e+010.00s1+6.67007650e+00-3.65314339e+001.8e-023.2e-022.8e+001.7e+000.00s2+1.36507017e+00+2.11936527e-024.6e-048.1e-041.3e+002.2e-010.00s3+5.85640966e-01+3.97564854e-012.6e-053.7e-031.9e-013.1e-020.00s4+4.53810895e-01+4.38464927e-016.4e-079.3e-051.5e-022.6e-030.00s5+4.40393096e-01+4.39961443e-011.6e-082.3e-064.3e-047.2e-050.00s6+4.40009842e-01+4.39999040e-014.0e-105.9e-081.1e-051.8e-060.00s7+4.40000247e-01+4.39999976e-011.0e-111.5e-092.7e-074.5e-080.00s8+4.40000006e-01+4.39999999e-012.5e-133.7e-116.8e-091.1e-090.01sTerminated.
-Method             : Interiorpointmethod.
-Primalobjective   : 4.3999999423925E-01-Dualobjective     : 4.3999999955250E-01-Num. threads       : 2-Num. iterations    : 8-Solverdetails     : Solverterminatedwithaprimal/dualoptimalstatus.
Interiorpointmethodterminated. Time : 0.005sOptimizersummary.          /*求解器最终选择的优化方法以及求解消耗的时间*/-Optimizerused     : Interiorpointmethod/*内点法*/-Optimizerstatus   : OPTIMAL-Totaltime         : 0.006sSolutionsummary.       Primalsolution-Objective          : 4.3999999424e-01/*目标函数最优解*/

联系我们

钉钉群号:32451444

邮箱地址:solver.damo@list.alibaba-inc.com

更多更新通知:https://solver.damo.alibaba.com

相关文章
|
6月前
|
达摩院 开发者 容器
「达摩院MindOpt」优化形状切割问题(MILP)
在制造业,高效地利用材料不仅是节约成本的重要环节,也是可持续发展的关键因素。无论是在金属加工、家具制造还是纺织品生产中,原材料的有效利用都直接影响了整体效率和环境影响。
「达摩院MindOpt」优化形状切割问题(MILP)
|
1月前
|
机器学习/深度学习 算法 数据可视化
如果你的PyTorch优化器效果欠佳,试试这4种深度学习中的高级优化技术吧
在深度学习领域,优化器的选择对模型性能至关重要。尽管PyTorch中的标准优化器如SGD、Adam和AdamW被广泛应用,但在某些复杂优化问题中,这些方法未必是最优选择。本文介绍了四种高级优化技术:序列最小二乘规划(SLSQP)、粒子群优化(PSO)、协方差矩阵自适应进化策略(CMA-ES)和模拟退火(SA)。这些方法具备无梯度优化、仅需前向传播及全局优化能力等优点,尤其适合非可微操作和参数数量较少的情况。通过实验对比发现,对于特定问题,非传统优化方法可能比标准梯度下降算法表现更好。文章详细描述了这些优化技术的实现过程及结果分析,并提出了未来的研究方向。
27 1
|
4月前
|
人工智能 算法 调度
优化问题之如何选择合适的优化求解器
优化问题之如何选择合适的优化求解器
|
4月前
|
达摩院 安全 调度
网络流问题--交通调度【数学规划的应用(含代码)】阿里达摩院MindOpt
本文探讨了如何利用数学规划工具MindOpt解决交通调度问题。交通调度涉及网络流分析,考虑道路容量、车辆限制、路径选择等因素,以实现高效运行。通过建立数学模型,利用MindOpt云平台和建模语言MAPL,设定流量最大化目标并确保流量守恒,解决实际的调度问题。案例展示了如何分配车辆从起点到终点,同时满足道路容量约束。MindOpt Studio提供在线开发环境,支持模型构建和求解,帮助优化大规模交通调度。
|
4月前
|
调度 决策智能
优化问题之优化求解器有哪些主要的评估特性
优化问题之优化求解器有哪些主要的评估特性
|
4月前
|
达摩院
人员排班【数学规划的应用(含代码)】阿里达摩院MindOpt
本文介绍了使用阿里巴巴达摩院的MindOpt工具解决人员排班的数学规划问题。人员排班在多个行业中至关重要,如制造业、医疗、餐饮和零售等。问题涉及多种约束,包括工作需求、员工能力、工作时间限制、连续工作天数及公平性。通过MindOpt云建模平台和建模语言MindOpt APL,建立数学模型并编写代码来解决最小化总上班班次的问题。案例中展示了如何声明集合、参数、变量和约束,并给出了部分代码示例。最后,通过MindOpt求解器得到最优解,并将结果输出到CSV文件中。
|
4月前
|
存储 达摩院 供应链
排产排程问题【数学规划的应用(含代码)】阿里达摩院MindOpt
**文章摘要:** 本文探讨了使用阿里巴巴达摩院的MindOpt优化求解器解决制造业中的排产排程问题。排产排程涉及物料流动、工序安排、设备调度等多个方面,通常通过数学规划方法建模。MindOpt支持线性规划、整数规划等,能有效处理大规模数据。案例以香皂制造工厂为例,考虑了多种油脂的购买、存储和生产计划,以及价格变化和存储成本。问题通过数学建模转化为MindOpt APL代码,求解器自动寻找最优解,以最大化利润。文章还提供了代码解析,展示了解决方案的细节,包括目标函数(利润最大化)、约束条件(如生产效率、库存管理)以及结果分析。
|
5月前
|
供应链 定位技术 数据库
仓库选址问题【数学规划的应用(含代码)】阿里达院MindOpt
使用阿里云MindOpt工具,文章展示了如何解决仓库选址的数学规划问题。该问题涉及构建工厂以供应多个商店,考虑因素包括建设成本、库存成本、运输成本和需求量。MindOpt是一个优化求解器,能处理大规模数据的数学规划问题。通过声明集合、参数、变量、目标函数和约束条件,构建模型并求解,以最小化总成本。文中还提到了不同行业的应用场景,如农业、制造业、零售业和电商,并提供了视频讲解和代码示例。
|
5月前
|
达摩院 供应链 调度
【FlowShop流水线作业排班问题【数学规划的应用(含代码)】阿里达摩院MindOpt】
本文探讨了使用阿里巴巴达摩院的MindOpt工具解决FlowShop流水线作业排班的数学规划问题。FlowShop涉及到多台机器、多个工序和多个作业,目标是通过优化排班最小化总生产耗时。MindOpt通过数学规划方法,如线性或混合整数线性规划,将问题建模并转化为代码,利用云建模平台MindOpt Studio和MindOpt APL建模语言进行求解。案例中详细介绍了参数定义、变量解析、约束设置和目标函数,展示了如何通过MindOpt进行建模和求解,以达到最优化的生产调度。此外,文章还提供了代码示例和结果解析,帮助读者理解如何实际应用MindOpt解决这类问题。
|
6月前
|
机器学习/深度学习 算法 测试技术
MindOpt APL向量化建模语法的介绍与应用(1)
向量化建模是一种高效的数学建模和编程技术,它涉及到对向量、矩阵和更高维数组进行操作,以实现操作的同时性和批量处理。在优化和数据分析等领域,向量化建模可以极大地提高计算效率,特别是当涉及到大量的重复计算时。由于向量化建模具有表述优势、操作优势、计算性能、可扩展性等优势,使得其适合于解决很大一类实际问题