二次规划问题用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


相关文章
|
存储 Windows
怎样格式化硬盘?四种硬盘格式化方法(含详细图文步骤)
这篇内容介绍了硬盘格式化的方法,包括为何要格式化硬盘(如快速清空数据、建立新分区、修复错误、改变文件系统类型)和四种格式化方式:1) 使用文件管理器,2) 通过磁盘管理器,3) 利用分区工具DiskGenius,4) 使用diskpart命令。在执行格式化前,务必备份重要数据,因为格式化会导致数据丢失。
|
开发框架 .NET Java
高校在线心理咨询系统的设计与实现(论文+源码)_kaic
高校在线心理咨询系统的设计与实现(论文+源码)_kaic
高校在线心理咨询系统的设计与实现(论文+源码)_kaic
|
4月前
|
弹性计算 关系型数据库 对象存储
阿里云国际实名账号vs 非实名账号:如何选择更适合你的方案?
阿里云国际站提供实名与非实名账号选择,实名账号可购买中国大陆云产品,适合需国内业务合规的企业;非实名账号适用于海外部署,无需备案,灵活便捷。根据业务需求选择,助力全球化部署。
|
9月前
|
编解码 监控 安全
JT1078和GB28181差别在哪里?
JT1078和GB28181分别是针对车载监控和公共安全监控设计的标准协议。JT1078专注于车载视频监控,适用于物流与交通场景,强调实时传输、编解码支持及无线环境下的数据安全性;而GB28181侧重于大规模公共安全监控,覆盖城市安防等领域,支持多协议交互与级联方案。两者在技术上有交集,需通过中间件实现互联互通,各有独特优势以满足不同需求。
490 8
|
机器学习/深度学习 达摩院
阿里达摩院MindOpt优化求解器-月刊(2024年4月)
【摘要】2024.04.30,阿里云发布了MindOpt优化求解器的新商品和功能。MindOpt现在已上架,提供超低价零售求解器,支持按需购买,可在阿里云平台上直接购买联网或不联网License。新版本V1.2发布,提升MILP性能,并增加PostScaling参数。此外,MindOpt Studio推出租户定制版,正处于邀测阶段。同时分享了使用MindOpt解决二分类SVM问题的案例。更多内容,可访问相关链接。
473 0
|
数据挖掘 C语言 C++
R语言是一种强大的统计分析工具,提供了丰富的函数和包用于时间序列分析。
【10月更文挑战第21天】时间序列分析是一种重要的数据分析方法,广泛应用于经济学、金融学、气象学、生态学等领域。R语言是一种强大的统计分析工具,提供了丰富的函数和包用于时间序列分析。本文将介绍使用R语言进行时间序列分析的基本概念、方法和实例,帮助读者掌握R语言在时间序列分析中的应用。
361 3
|
运维 关系型数据库 MySQL
掌握taskset:优化你的Linux进程,提升系统性能
在多核处理器成为现代计算标准的今天,运维人员和性能调优人员面临着如何有效利用这些处理能力的挑战。优化进程运行的位置不仅可以提高性能,还能更好地管理和分配系统资源。 其中,taskset命令是一个强大的工具,它允许管理员将进程绑定到特定的CPU核心,减少上下文切换的开销,从而提升整体效率。
掌握taskset:优化你的Linux进程,提升系统性能
|
SQL 存储 JSON
Flink+Paimon+Hologres 构建实时湖仓数据分析
本文整理自阿里云高级专家喻良,在 Flink Forward Asia 2023 主会场的分享。
72549 8
Flink+Paimon+Hologres 构建实时湖仓数据分析
|
达摩院 API C++
MindOpt--C++语言-对一个简单的混合整数规划问题建模求解
MindOpt是达摩院决策智能实验室研究的一款优化求解器,目前在优化求解线性规划问题这一功能上取得不错的成绩,希望大家能够帮我们多多打磨其他功能(混合整数线性规划、二次规划、半定规划目前都在公测),让我们的MindOpt在优化求解器这板块成为国产之光。
MindOpt--C++语言-对一个简单的混合整数规划问题建模求解
|
SQL 关系型数据库 MySQL
MySQL数据库——触发器-介绍、语法(创建,查看,删除)
MySQL数据库——触发器-介绍、语法(创建,查看,删除)
1111 0