5.2.3. C++ 的MILP建模和优化

在本节中,我们将使用 MindOpt C++ 语言的 API 来建模以及求解 混合整数线性规划问题示例 中的问题。

5.2.3.1. 按行输入:MdoMiloEx1

首先,引入头文件:

27#include "MindoptCpp.h"

并创建优化模型:

33    /*------------------------------------------------------------------*/
34    /* Step 1. Create a model and change the parameters.                */
35    /*------------------------------------------------------------------*/
36    /* Create an empty model. */
37    MdoModel model;

接下来,我们通过 mindopt::MdoModel::setIntAttr() 将目标函数设置为 最小化 ,并调用 mindopt::MdoModel::addVar() 来添加四个优化变量,定义其下界、上界、名称和类型(有关 mindopt::MdoModel::setIntAttr()mindopt::MdoModel::addVar() 的详细使用方式,请参考 C++ 接口函数):

41        /*------------------------------------------------------------------*/
42        /* Step 2. Input model.                                             */
43        /*------------------------------------------------------------------*/
44        /* Change to minimization problem. */
45        model.setIntAttr(MDO_INT_ATTR::MIN_SENSE, MDO_YES);
46
47        /* Add variables. */
48        std::vector<MdoVar> x;
49        x.push_back(model.addVar(0.0, 10.0,         1.0, "x0", MDO_YES));
50        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, "x1", MDO_YES));
51        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, "x2", MDO_YES));
52        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, "x3", MDO_NO));

Note

在函数 mindopt::MdoModel::addVar() 中,最后一个参数位是 is_integer ,设置为 MDO_YES 代表这个变量是整形变量。

接着,我们开始添加线性约束:

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

问题输入完成后,再调用 mindopt::MdoModel::solveProb() 求解优化问题,并通过 mindopt::MdoModel::displayResults() 查看优化结果:

58        /*------------------------------------------------------------------*/
59        /* Step 3. Solve the problem and populate the result.               */
60        /*------------------------------------------------------------------*/
61        /* Solve the problem. */
62        model.solveProb();
63        model.displayResults();

文件链接 MdoMiloEx1.cpp 提供了完整源代码:

 1/**
 2 *  Description
 3 *  -----------
 4 *
 5 *  Linear optimization (row-wise input).
 6 *
 7 *  Formulation
 8 *  -----------
 9 *
10 *  Minimize
11 *    obj: 1 x0 + 1 x1 + 1 x2 + 1 x3
12 *  Subject To
13 *   c0 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
14 *   c1 : 1 x0 - 1 x2 + 6 x3 = 1
15 *  Bounds
16 *    0 <= x0 <= 10
17 *    0 <= x1
18 *    0 <= x2
19 *    0 <= x3
20 *  Integers
21 *    x0 x1 x2
22 *  End
23 */
24#include <iostream>
25#include <vector>
26#include "MindoptCpp.h"
27
28using namespace mindopt;
29
30int main(void)
31{
32    /*------------------------------------------------------------------*/
33    /* Step 1. Create a model and change the parameters.                */
34    /*------------------------------------------------------------------*/
35    /* Create an empty model. */
36    MdoModel model;
37
38    try 
39    {
40        /*------------------------------------------------------------------*/
41        /* Step 2. Input model.                                             */
42        /*------------------------------------------------------------------*/
43        /* Change to minimization problem. */
44        model.setIntAttr(MDO_INT_ATTR::MIN_SENSE, MDO_YES);
45
46        /* Add variables. */
47        std::vector<MdoVar> x;
48        x.push_back(model.addVar(0.0, 10.0,         1.0, "x0", MDO_YES));
49        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, "x1", MDO_YES));
50        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, "x2", MDO_YES));
51        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, "x3", MDO_NO));
52
53        /* Add constraints. */
54        model.addCons(1.0, MDO_INFINITY, 1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3], "c0");
55        model.addCons(1.0, 1.0,          1.0 * x[0]              - 1.0 * x[2] + 6.0 * x[3], "c1");
56
57        /*------------------------------------------------------------------*/
58        /* Step 3. Solve the problem and populate the result.               */
59        /*------------------------------------------------------------------*/
60        /* Solve the problem. */
61        model.solveProb();
62        model.displayResults();
63    }
64    catch (MdoException & e)
65    {
66        std::cerr << "===================================" << std::endl;
67        std::cerr << "Error   : code <" << e.getResult() << ">" << std::endl;
68        std::cerr << "Reason  : " << model.explainResult(e.getResult()) << std::endl;
69        std::cerr << "===================================" << std::endl;
70
71        return static_cast<int>(e.getResult());
72    }
73
74    return static_cast<int>(MDO_OKAY);
75}