C语言如何使用MindOpt建模并求解线性规划问题

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

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

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


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


安装

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

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


线性规划

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


入门案例

一位员工每天要负责处理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
  • 这个列题最后求出的最优解是每天参与a任务三小时、b任务5小时。

image.png


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

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

image.png

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


进阶算例

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

接下来把上述的问题带入下文的数学算例,用MindOpt优化求解器进行求解。

线性规划问题示例:

image.png


MindOpt+c语言的建模与优化

核心使用的几个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 接口函数

下面是完整的例子,可复制存为MdoLoEx1.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;                                           \
}

int main(void)
{
    /* 变量 */
    char str[1024] = { "\0" };
    MdoMdl * model = NULL;
    MdoResult code = MDO_OKAY;
    MdoStatus status = MDO_UNKNOWN;

    const int    row1_idx[] = { 0,   1,   2,   3   };
    const double row1_val[] = { 1.0, 1.0, 2.0, 3.0 };
    const int    row2_idx[] = { 0,    2,   3   };
    const double row2_val[] = { 1.0, -1.0, 6.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_NO));
    MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x1", MDO_NO));
    MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x2", MDO_NO));
    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"));

    /*------------------------------------------------------------------*/
    /* Step 3. 解决问题并填充结果。             */
    /*------------------------------------------------------------------*/
    /* 解决问题。 */
    /*调用 Mdo_solveProb() 求解优化问题,并通过 Mdo_displayResults() 查看优化结果*/
    MDO_CHECK_CALL(Mdo_solveProb(model));
    Mdo_displayResults(model);

    /*------------------------------------------------------------------*/
    /* Step 4. 释放模型。                                          */
    /*------------------------------------------------------------------*/
    /* Free the model. */
    Mdo_freeMdl(&model);

    return (int)code;
}

MindOpt求解的结果

如何运行MdoLoEx1.c文件

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

#运行文件放在“源文件”下,图片被挡住了不好意思。

*linux和mac系统 在命令行输入

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

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

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.000s

Simplex method started.                     /*使用单纯形法*/
    Model fingerprint: ==gZ3B2djdXZ

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

Concurrent optimization terminated. /*求解器最终选择的优化方法以及求解消耗的时间*/
    Optimizer summary.
    - Optimizer used     : Simplex method  /*单纯形法*/
- Optimizer status   : OPTIMAL
- Total time         : 0.005s

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

联系我们

钉钉:damodi

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

相关文章
|
算法 安全 机器人
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 达摩院自己的建模语言!
|
人工智能 达摩院 算法
什么是优化技术?给算法小白同学的快速讲解和上手文
经常被尊贵的客户问,什么是优化技术,能干啥?小白一文快速入门,并掌握业界前沿的高效上手方案!
717 1
|
达摩院 算法 Java
选择优化求解器的关键因素:以MindOpt为例
选择一款适合自己业务需求的求解器我们一般需要考量什么呢?可求解的问题类型?问题规模?本文将介绍一些需要考虑的重要因素,并且介绍阿里达摩院MindOpt优化求解器在这些因素下的表现。
|
达摩院 Python
阿里达摩院MindOpt优化求解器-月刊(2024年6月)
**阿里达摩院MindOpt优化求解器2024年6月月刊概览:** - 发布新功能,MAPL建模语言V2.5上线,Python APIs全面升级,旧版本不兼容。 提供快速入门教程、示例代码展示如何用Python调用MAPL。MindOpt Studio租户版新增Gradio支持,便于开发WebAPP,提供了案例源码展示如何开发。引入新案例: 1. 巡检线路的排班-2017全国大学生数学建模竞赛D题。包含最短路模型、TSP模型、弧分割模型。2. 商品组合定价策略:探讨如何最赚钱的加购区商品定价。
222 0
|
缓存 达摩院 算法
如何通过阿里达摩院MindOpt获得MILP多个解
在2024年1月达摩院新发布的MindOpt 优化求解器V1.1.0版本中,新增加了一个"MIP/SolutionNumber"参数,可以用于获取MILP多个解。有些业务里,会想要找到更多的可行解,目标值不一定最优,用于给业务指导。本篇案例将讲解如何使用此功能。
455 1
|
机器学习/深度学习 人工智能 达摩院
MindOpt工具是如何做到配套使用的?请看此篇
MindOpt是阿里巴巴达摩院决策职能实验室研发的专注于优化领域,提供智能优化解决方案的品牌。主要的目标是帮助客户通过先进的优化算法和技术,实现业务流程的最佳化,提升效率,降低成本,并最大化业务价值。
|
机器学习/深度学习 人工智能 达摩院
MindOpt——优化虚拟电厂智能调度问题(二)
智慧楼宇调度,是在保证社区负荷需求的情况下,通过储能设备的指令控制,以用电经济性、环保性和对电网稳定性为综合目标的一种调度场景。
MindOpt——优化虚拟电厂智能调度问题(二)
|
达摩院 算法 API
阿里达摩院MindOpt优化求解器-月刊(2023年7月)
阿里达摩院MindOpt优化求解器-7月刊,新增人员排班、仓库选址优化的案例,包含源代码,新版本MindOpt求解器V1.0的API重大升级,邀请内测。
473 0
阿里达摩院MindOpt优化求解器-月刊(2023年7月)
Python语言如何使用MindOpt建模并求解混合整数线性规划问题
MindOpt是一款高效的优化算法软件包,求解算法实现了线性规划(LP)、混合整数线性规划(MILP)、二次规划(QP),可以支持命令行、c、c++、java和python调用。接下来我们将发布一系列文章,讲述各个语言如何使用 MindOpt 来求解数学规划问题。
Python语言如何使用MindOpt建模并求解混合整数线性规划问题