二次规划问题用MindOpt C++怎么进行建模优化

简介: MindOpt是达摩院决策智能实验室研究的一款优化求解器,目前在优化求解线性规划问题这一功能上取得不错的成绩,希望大家能够帮我们多多打磨其他功能(混合整数线性规划、二次规划、半定规划目前都在公测),让我们的MindOpt在优化求解器这板块成为国产之光。

二次规划问题在生活中非常常见,广泛体现在时间调度、时间调度,规模经济学,工程设计以及控制领域,设施分配问题,选址问题,目前MindOpt优化求解器求解二次规划问题的功能正在公测,感兴趣的小伙伴可以去了解一下。本文将会重点讲述如何使用mindopt c++ 语言的api来建模优化二次规划问题。


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


下载安装

用户可以点这里下载安装MindOpt优化求解器

开通算法服务控制台(免费的)

MindOpt的更多信息官网


二次规划

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


关于优化的类别,有很多,比如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


数学算例

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

二次规划问题示例:

image.png

C++和MindOpt代码实现

核心使用的几个APIs是:

 MdoModel model;

model.setIntAttr(MDO_INT_ATTR::MIN_SENSE, MDO_YES);

model.addCons(1.0, MDO_INFINITY, 1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3], "c0");
model.addCons(1.0, 1.0,          1.0 * x[0]              - 1.0 * x[2] + 6.0 * x[3], "c1");

model.solveProb();
model.displayResults();

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

#include <iostream>
#include <vector>
/*引入头文件*/
#include "MindoptCpp.h"

using namespace mindopt;

int main(void)
{
    /*------------------------------------------------------------------*/
    /* Step 1. 创建模型并更改参数。                */
    /*------------------------------------------------------------------*/
    /* 创建一个空模型。 */
    MdoModel model;

    try 
    {
        /*------------------------------------------------------------------*/
        /* Step 2. 输入模型。                                             */
        /*------------------------------------------------------------------*/
        /* 通过 mindopt::MdoModel::setIntAttr() 将目标函数设置为 最小化 */
        model.setIntAttr(MDO_INT_ATTR::MIN_SENSE, MDO_YES);

        /* 调用 mindopt::MdoModel::addVar() 来添加四个优化变量,定义其下界、上界、名称和类型 */
        std::vector<MdoVar> x;
        x.push_back(model.addVar(0.0, 10.0,         1.0, "x0", MDO_NO));
        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, "x1", MDO_NO));
        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, "x2", MDO_NO));
        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, "x3", MDO_NO));

        /* 添加约束 */
        model.addCons(1.0, MDO_INFINITY, 1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3], "c0");
        model.addCons(1.0, 1.0,          1.0 * x[0]              - 1.0 * x[2] + 6.0 * x[3], "c1");

        /* 添加二次目标矩阵 Q.
         *
         * 1. 目标函数定义为c^Tx + 1/2 x^TQx,其中Q以坐标格式存储。
         * 2. Q 将在内部缩放 1/2。
         * 3. 为保证Q的对称性,用户只需输入下三角部分即可
         *
         * Q = [ 1.0  0.5  0    0   ]
         *     [ 0.5  1.0  0    0   ]
         *     [ 0.0  0.0  1.0  0   ]
         *     [ 0    0    0    1.0 ]
         */
        /*调用 mindopt::MdoModel::setQuadraticElements() 来设置目标的二次项系数 。
          前两组输入向量分别表示二次项中所有非零项的两个变量的索引,
          最后一组输入向量是与之相对应的非零系数值。*/
        model.setQuadraticElements
        (
            { x[0], x[1], x[1], x[2], x[3] },
            { x[0], x[0], x[1], x[2], x[3] },
            {  1.0,  0.5,  1.0,  1.0,  1.0 }
        );

        /*------------------------------------------------------------------*/
        /* Step 3.  解决问题并填充结果。               */
        /*------------------------------------------------------------------*/
        /* 调用 mindopt::MdoModel::solveProb() 求解优化问题,
           并通过 mindopt::MdoModel::displayResults() 查看优化结果 
          */
        model.solveProb();
        model.displayResults();
    }
    catch (MdoException & e)
    {
        std::cerr << "===================================" << std::endl;
        std::cerr << "Error   : code <" << e.getResult() << ">" << std::endl;
        std::cerr << "Reason  : " << model.explainResult(e.getResult()) << std::endl;
        std::cerr << "===================================" << std::endl;

        return static_cast<int>(e.getResult());
    }

    return static_cast<int>(MDO_OKAY);
}

MindOpt求解的结果

运行MdoQoEx1.cpp文件的步骤

linux和mac系统直接在命令行输入

cd <MDOHOME>/<VERSION>/examples/CPP
make -f Makefile all
./MdoQoEx1

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

#运行方式与前文    一致,只需要修改文件就好;把MdoLoEx1.cpp换成MdoQoEx1.cpp

C++.gif

如上文所述,运行MdoMiloEx1.cpp文件,得到求解的结果如下所示,/**/号里面是我添加的注释。

Model summary.               /*模型摘要*/
 - Num. variables     : 4
 - Num. constraints   : 2
 - Num. nonzeros      : 7
 - Bound range        : [1.0e+00,1.0e+01]
 - Objective range    : [1.0e+00,1.0e+00]
 - Quad. obj. range   : [5.0e-01,1.0e+00]
 - Matrix range       : [1.0e+00,6.0e+00]

Presolver started.
Presolver terminated. Time : 0.001s

Interior point method started.   /*内点法*/
 Iter         PrimObj         DualObj PrimFea DualFea  GapFea      Mu   Time
    0 +5.21950421e+01 -5.93593455e+01 1.3e+00 8.0e-01 2.1e+00 1.5e+01   0.03s
    1 +5.75093325e+00 -3.28624247e+00 3.2e-02 2.0e-02 2.8e+00 1.5e+00   0.04s
    2 +1.19681205e+00 +1.03397025e-04 8.1e-04 3.7e-03 1.2e+00 2.0e-01   0.04s
    3 +6.52164783e-01 +3.52420863e-01 1.7e-04 3.7e-03 3.0e-01 4.9e-02   0.05s
    4 +4.65540318e-01 +4.35143347e-01 4.2e-06 9.3e-05 3.0e-02 5.1e-03   0.06s
    5 +4.40907312e-01 +4.39861230e-01 1.0e-07 2.3e-06 1.0e-03 1.7e-04   0.07s
    6 +4.40022716e-01 +4.39996554e-01 2.6e-09 5.8e-08 2.6e-05 4.4e-06   0.08s
    7 +4.40000569e-01 +4.39999914e-01 6.5e-11 1.5e-09 6.6e-07 1.1e-07   0.08s
    8 +4.40000014e-01 +4.39999998e-01 1.6e-12 3.7e-11 1.6e-08 2.7e-09   0.09s
    9 +4.40000000e-01 +4.40000000e-01 4.1e-14 9.1e-13 4.1e-10 6.9e-11   0.10s
Terminated.
 - Method             : Interior point method.
 - Primal objective   : 4.3999999966807E-01
 - Dual objective     : 4.3999999996074E-01
 - Num. threads       : 2
 - Num. iterations    : 9
 - Solver details     : Solver terminated with a primal/dual optimal status.

Interior point method terminated. Time : 0.107s

Optimizer summary.
 - Optimizer used     : Interior point method
 - Optimizer status   : OPTIMAL
 - Total time         : 0.116s

Solution summary.       Primal solution
 - Objective          : 4.3999999967e-01       /*目标函数最优解*/


联系我们

钉钉:damodi

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


相关文章
|
达摩院 Linux API
阿里达摩院MindOpt求解器V1.1新增C#接口
阿里达摩院MindOpt求解器发布最新版本V1.1,增加了C#相关API和文档。优化求解器产品是求解优化问题的专业计算软件,可广泛各个行业。阿里达摩院从2019年投入自研MindOpt优化求解器,截止目前经历27个版本的迭代,取得了多项国内和国际第一的成绩。就在上个月,2023年12月,在工信部产业发展促进中心等单位主办的首届能源电子产业创新大赛上,MindOpt获得电力用国产求解器第一名。本文将为C#开发者讲述如何下载安装MindOpt和C#案例源代码。
455 3
阿里达摩院MindOpt求解器V1.1新增C#接口
|
算法 安全 机器人
Python语言如何使用MindOpt建模并求解二次规划问题
MindOpt是一款高效的优化算法软件包,求解算法实现了线性规划(LP)、混合整数线性规划(MILP)、二次规划(QP),可以支持命令行、c、c++、java和python调用。接下来我们将发布一系列文章,讲述各个语言如何使用 MindOpt 来求解数学规划问题。
Python语言如何使用MindOpt建模并求解二次规划问题
MindOpt APL 达摩院自己的建模语言!
MindOpt建模语言(MindOpt Algebraic Programming Language, MindOpt APL, 简称为MAPL)是MindOpt团队研发的一种代数建模语言。相比与其他的语言,MAPL语法相对较少且自然,很贴近数学语言。用MAPL描述数学规划模型与用数学公式进行描述非常类似。
MindOpt APL 达摩院自己的建模语言!
|
机器学习/深度学习 达摩院
阿里达摩院MindOpt优化求解器-月刊(2024年4月)
【摘要】2024.04.30,阿里云发布了MindOpt优化求解器的新商品和功能。MindOpt现在已上架,提供超低价零售求解器,支持按需购买,可在阿里云平台上直接购买联网或不联网License。新版本V1.2发布,提升MILP性能,并增加PostScaling参数。此外,MindOpt Studio推出租户定制版,正处于邀测阶段。同时分享了使用MindOpt解决二分类SVM问题的案例。更多内容,可访问相关链接。
370 0
|
达摩院 供应链 JavaScript
网络流问题--仓储物流调度【数学规划的应用(含代码)】阿里达摩院MindOpt
本文通过使用MindOpt工具优化仓储物流调度问题,旨在提高物流效率并降低成本。首先,通过考虑供需匹配、运输时间与距离、车辆容量、仓库储存能力等因素构建案例场景。接着,利用数学规划方法,包括线性规划和网络流问题,来建立模型。在网络流问题中,通过定义节点(资源)和边(资源间的关系),确保流量守恒和容量限制条件下找到最优解。文中还详细介绍了MindOpt Studio云建模平台和MindOpt APL建模语言的应用,并通过实例展示了如何声明集合、参数、变量、目标函数及约束条件,并最终解析了求解结果。通过这些步骤,实现了在满足各仓库需求的同时最小化运输成本的目标。
|
达摩院 安全 调度
网络流问题--交通调度【数学规划的应用(含代码)】阿里达摩院MindOpt
本文探讨了如何利用数学规划工具MindOpt解决交通调度问题。交通调度涉及网络流分析,考虑道路容量、车辆限制、路径选择等因素,以实现高效运行。通过建立数学模型,利用MindOpt云平台和建模语言MAPL,设定流量最大化目标并确保流量守恒,解决实际的调度问题。案例展示了如何分配车辆从起点到终点,同时满足道路容量约束。MindOpt Studio提供在线开发环境,支持模型构建和求解,帮助优化大规模交通调度。
|
达摩院 调度
使用达摩院MindOpt优化交通调度_最大化通行量—线性规划问题
在数学规划中,网络流问题是指一类基于网络模型的流量分配问题。网络流问题的目标是在网络中分配资源,使得网络的流量满足一定的限制条件,并且使得某些目标函数最小或最大化。网络流问题通常涉及一个有向图,图中每个节点表示一个资源,每条边表示资源之间的关系。边上有一个容量值,表示该边上最多可以流动的资源数量。流量从源节点开始流出,经过一系列中间节点,最终到达汇节点。在这个过程中,需要遵守一定的流量守恒和容量限制条件。
|
达摩院 算法 Java
选择优化求解器的关键因素:以MindOpt为例
选择一款适合自己业务需求的求解器我们一般需要考量什么呢?可求解的问题类型?问题规模?本文将介绍一些需要考虑的重要因素,并且介绍阿里达摩院MindOpt优化求解器在这些因素下的表现。
|
达摩院 算法 决策智能
如何选择旅游路线,使得假期旅游路费最少?
旅行是许多人的热爱,但是在规划一个完美的假期时,找到最经济的路线常常是一个挑战。这里就需要引入一个著名的优化问题——旅行商问题。本文将介绍TSP的基础知识,并使用MTZ消除子环方法优化一个简单的TSP问题的示例。