5.1.3. C++ 的LP建模和优化

在本节中,我们将使用 MindOpt C++ API,以按行输入的形式来建模以及求解 线性规划问题示例 中的问题。

首先,引入头文件:

24#include "MindoptCpp.h"

并创建优化模型:

33    MDOEnv env = MDOEnv();
34    MDOModel model = MDOModel(env);

接下来,我们通过 MDOModel::set() 将目标函数设置为 最小化,并调用 MDOModel::addVar() 来添加四个优化变量(有关 MDOModel::set()MDOModel::addVar() 的详细使用方式,请参考 C++ API):

41        /* Change to minimization problem. */
42        model.set(MDO_IntAttr_ModelSense, MDO_MINIMIZE);
43
44        /* Add variables. */
45        std::vector<MDOVar> x;
46        x.push_back(model.addVar(0.0, 10.0,         1.0, MDO_CONTINUOUS, "x0"));
47        x.push_back(model.addVar(0.0, MDO_INFINITY, 2.0, MDO_CONTINUOUS, "x1"));
48        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, MDO_CONTINUOUS, "x2"));
49        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, MDO_CONTINUOUS, "x3"));

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

51        /* Add constraints. */
52        model.addConstr(1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3] >= 1.0, "c0");
53        model.addConstr(1.0 * x[0]              - 1.0 * x[2] + 6.0 * x[3] == 1.0, "c1");

问题输入完成后,再调用 MDOModel::optimize() 求解优化问题:

58        model.optimize();

求解完成后,可以通过获取属性值的方式来获取对应解的优化目标值和变量的取值:

59        if (model.get(MDO_IntAttr_Status) == MDO_OPTIMAL)
60        {
61            cout << "Optimal objective value is: " << model.get(MDO_DoubleAttr_ObjVal) << endl;
62            cout << "Decision variables: " << endl;
63            int i = 0;
64            for (auto v : x)
65            {
66                cout << "x[" << i++ << "] = " << v.get(MDO_DoubleAttr_X) << endl;
67            }
68        }
69        else
70        {
71            cout << "No feasible solution." << endl;
72        }

示例 MdoLoEx1.cpp 提供了完整源代码:

 1/**
 2 *  Description
 3 *  -----------
 4 *
 5 *  Linear optimization (row-wise input).
 6 *
 7 *  Formulation
 8 *  -----------
 9 *
10 *  Minimize
11 *    obj: 1 x0 + 2 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 *  End
21 */
22#include <iostream>
23#include <vector>
24#include "MindoptCpp.h"
25
26using namespace std;
27
28int main(void)
29{
30    /*------------------------------------------------------------------*/
31    /* Step 1. Create environment and model.                            */
32    /*------------------------------------------------------------------*/
33    MDOEnv env = MDOEnv();
34    MDOModel model = MDOModel(env);
35
36    try
37    {
38        /*------------------------------------------------------------------*/
39        /* Step 2. Input model.                                             */
40        /*------------------------------------------------------------------*/
41        /* Change to minimization problem. */
42        model.set(MDO_IntAttr_ModelSense, MDO_MINIMIZE);
43
44        /* Add variables. */
45        std::vector<MDOVar> x;
46        x.push_back(model.addVar(0.0, 10.0,         1.0, MDO_CONTINUOUS, "x0"));
47        x.push_back(model.addVar(0.0, MDO_INFINITY, 2.0, MDO_CONTINUOUS, "x1"));
48        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, MDO_CONTINUOUS, "x2"));
49        x.push_back(model.addVar(0.0, MDO_INFINITY, 1.0, MDO_CONTINUOUS, "x3"));
50
51        /* Add constraints. */
52        model.addConstr(1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3] >= 1.0, "c0");
53        model.addConstr(1.0 * x[0]              - 1.0 * x[2] + 6.0 * x[3] == 1.0, "c1");
54
55        /*------------------------------------------------------------------*/
56        /* Step 3. Solve the problem and populate optimization result.      */
57        /*------------------------------------------------------------------*/
58        model.optimize();
59        if (model.get(MDO_IntAttr_Status) == MDO_OPTIMAL)
60        {
61            cout << "Optimal objective value is: " << model.get(MDO_DoubleAttr_ObjVal) << endl;
62            cout << "Decision variables: " << endl;
63            int i = 0;
64            for (auto v : x)
65            {
66                cout << "x[" << i++ << "] = " << v.get(MDO_DoubleAttr_X) << endl;
67            }
68        }
69        else
70        {
71            cout << "No feasible solution." << endl;
72        }
73    } 
74    catch (MDOException& e) 
75    { 
76        std::cout << "Error code = " << e.getErrorCode() << std::endl;
77        std::cout << e.getMessage() << std::endl;
78    } 
79    catch (...) 
80    { 
81        std::cout << "Error during optimization." << std::endl;
82    }
83
84    return static_cast<int>(MDO_OKAY);
85}