MindOpt也能使用C++ 来建模求解线性规划问题?

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

线性规划问题在生活中一般会遇到如何利用现有资源来安排生产,以取得最大经济效益的问题,下文我们也将讲述一个排产排程的例子,求最大经济效益问题,但我们今天要重点展示的是使用MindOpt C++ 语言的 API 来建模以及求解一个目标函数最小化的算例(比如风险最小化、资源利用)。


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


线性规划

线性规划问题我个人认为是在线性的目标和约束中,找出一个最优解(如最大利润或最低成本)。线性规划可以广泛的应用在我们的生活中,解决资源利用、人力调配、生产安排等问题。

线性规划问题可以用以下数学公式来描述:

image.png

公式参考自:https://solver.damo.alibaba.com/doc/html/model/lp/linear%20problem.html


入门案例

一位员工每天要负责处理a任务(生成零部件) 和b任务(组装产品)。其参与a任务的报酬为100元/小时,b任务的报酬为150元/小时。工厂要求该员工每天在每个任务上花费至少 3 个小时。已知该员工每天工作8小时(因此在 6 小时之外,可以自行决定 2 小时如何工作),那么他该如何在两项任务上分配时间以得到尽可能多的报酬?

  • 以上问题可以被称为任务分配问题,也可以被视为一个简单的排产排程问题,由于该员工要决策时间分配,我们引入决策变量 Xa和 Xb用于表示该工人投入在任务和任务中的时长。由问题描述可知,这些变量需要满足Xa+Xb=8 和 Xa>=3,Xb>=3。
  • 此外,该工人的目标是获得尽可能多的报酬。在定义如上三要素后,我们可以建立如下的数学规划问题
  • 决策变量: Xa,Xb
  • 目标函数: maxmize 100Xa + 150Xb
  •     约束:  s.t.  Xa + Xb = 8
  •                      Xa>=3 , Xb>=3

image.png


进阶算例

在上文的例子,是一个简单的线性规划问题,只有两个决策变量,一个约束条件,而下文线性规划问题示例中的问题涉及到四个决策变量,两个约束条件,人工去求最优解呢,需要先把线性规划问题转换为标准形式,然后制表、入基、出基、换基,最后迭代得出最优解,过程比较复杂,那么我们可以使用商用求解器 MindOpt ,让计算机来帮助我们求解。


数学算例比较抽象,但要找到一个和线性规划问题示例中的问题相匹配的文字列题比较困难,所以我们在这里做一个假设,把它当成是一个人力调配的问题,求解的是一个目标函数的最小值,也就是花费最低成本去解决问题


我们把上述的假设带入下文的数学算例,用MindOpt优化求解器进行求解。

线性规划问题示例:

image.png


MindOpt + C++语言的建模与优化

核心使用的几个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();

下面是完整的例子,可复制存为MdoLoEx1.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() 来添加约束。 */
            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");

            /*------------------------------------------------------------------*/
            /* 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);
}

如何编译及运行MdoLoEx1.cpp文件

linux和Mac系统直接在命令行输入以下代码

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

windows系统本例是在Visual Studio上运行,版本为2019;c++和c的操作步骤大体是一致的只需要修改library文件和添加 .cpp 文件。

C++.gif

运行MdoLoEx1.cpp文件后,得到求解的结果如下所示,/**/号里面是小编的注释

Concurrent optimization started.     /*并发优化*/
 - Num. threads       : 2
 - Num. optimizers    : 2
 - Registered optimizers.
   +                  : Simplex method (1 thread, enabled output)
   +                  : Interior point method (1 thread, disabled output)

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]
 - Matrix range       : [1.0e+00,6.0e+00]

Presolver started.
Presolver terminated. Time : 0.001s

Simplex method started.

    Iteration       Objective       Dual Inf.     Primal Inf.     Time
            0     0.00000e+00      0.0000e+00      1.0000e+00     0.05s
            2     4.00000e-01      0.0000e+00      0.0000e+00     0.06s
Postsolver started.
Simplex method terminated. Time : 0.036s

Concurrent optimization terminated.
Optimizer summary.
 - Optimizer used     : Simplex method
 - Optimizer status   : OPTIMAL
 - Total time         : 0.085s

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

下载安装

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

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


联系我们

钉钉:y7r_yr2crky16

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


相关文章
|
7月前
|
人工智能 自然语言处理 达摩院
MindOpt 云上建模求解平台:多求解器协同优化
数学规划是一种数学优化方法,主要是寻找变量的取值在特定的约束情况下,使我们的决策目标得到一个最大或者最小值的决策。
|
存储 达摩院
「达摩院MindOpt」线性规划用于排程排程问题(02)
排产排程、原料采购、仓储存放等是制造业降本增效的关键问题。
「达摩院MindOpt」线性规划用于排程排程问题(02)
|
存储 达摩院
「达摩院MindOpt」线性规划用于排程排程问题(03)
比上一篇问题02中,我们只考虑了一次性的采购和生产计划,实际中的排产排程问题要更加复杂和精细。例如,我们要考虑未来三个月内采购和排产排程计划。其中,原材料每个月的采买价格均有不同,并且原材料购买后的存储也需要成本开销。在本节中,我们将考虑这样一个相对复杂的排产排程的决策问题。
「达摩院MindOpt」线性规划用于排程排程问题(03)
|
7月前
|
机器学习/深度学习 算法 测试技术
MindOpt APL向量化建模语法的介绍与应用(1)
向量化建模是一种高效的数学建模和编程技术,它涉及到对向量、矩阵和更高维数组进行操作,以实现操作的同时性和批量处理。在优化和数据分析等领域,向量化建模可以极大地提高计算效率,特别是当涉及到大量的重复计算时。由于向量化建模具有表述优势、操作优势、计算性能、可扩展性等优势,使得其适合于解决很大一类实际问题
|
7月前
|
测试技术 索引
MindOpt APL向量化建模语法的介绍与应用(2)
在数据科学、工程优化和其他科学计算领域中,向量和矩阵的运算是核心组成部分。MAPL作为一种数学规划语言,为这些领域的专业人员提供了强大的工具,通过向量式和矩阵式变量声明以及丰富的内置数学运算支持,大大简化了数学建模和优化问题的处理。在本文中,我们将探索MAPL的这些特性,并且通过示例来展示如何有效使用这些工具。
|
7月前
|
开发框架 自然语言处理 达摩院
MindOpt APL,可以支持调用几十种求解器的建模语言
建模语言可以提供更高级、更灵活的问题描述方式,从而提高问题的理解和求解效率。它可以加速问题的开发和部署过程,促进不同领域之间的合作和交流,从而推动问题求解的进展和创新。
MindOpt APL建模语言自定小义函数的重要性和示例
在编程和建模语言中,函数是一段独立的、可重复使用的代码块,用于执行特定任务。在MindOpt APL中,自定义函数的使用非常重要,因为它们提高了建模过程的效率、可读性和灵活性。
|
达摩院 数据格式 索引
「达摩院MindOpt APL 建模语言」语法说明 print 将结果写表格文件
不同的编程语言写入表格文件的方式均不相同,下面将展示MindOpt APL建模语言的方式。
|
7月前
|
人工智能 算法 决策智能
MindOpt云上建模求解平台功能的简单介绍
MindOpt云上建模求解平台是阿里巴巴达摩院研发的一款“优化领域”的云平台。它结合了最新的算法研究和云技术,为用户提供了一个易于使用的界面和强大的后台计算能力。该平台支持广泛的优化问题,包括线性规划、整数规划、非线性规划和混合整数规划等。
MindOpt V1.0优化种植计划问题,新的建模方法
种植计划是指农业生产中针对不同农作物的种植时间、面积和种植方式等方面的规划安排。根据具体情况进行合理的规划和安排,以实现农作物的高产、优质和可持续发展。
MindOpt V1.0优化种植计划问题,新的建模方法