5.2.6. C# 的MILP建模与优化

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

首先,创建优化模型:

31            // Create model
32            MDOEnv env = new MDOEnv(); 
33            MDOModel model = new MDOModel(env); 
34            model.Set(MDO.StringAttr.ModelName, "MILP_01");

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

38                // Change to minimization problem.
39                model.Set(MDO.IntAttr.ModelSense, MDO.MINIMIZE);
40
41                // Add variables.
42                MDOVar[] x = new MDOVar[4];
43                x[0] = model.AddVar(0.0,         10.0, 1.0, 'I', "x0");
44                x[1] = model.AddVar(0.0, MDO.INFINITY, 2.0, 'I', "x1");
45                x[2] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'I', "x2");
46                x[3] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x3");

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

48                // Add constraints.
49                double[][] consV = new double[][]{
50                    new double[] { 1.0, 1.0, 2.0, 3.0},
51                    new double[] { 1.0, 0,  -1.0, 6.0} 
52                };
53
54                MDOLinExpr tempLinExpr1 = new MDOLinExpr();
55                tempLinExpr1.AddTerms(consV[0], x);
56                model.AddConstr(tempLinExpr1, MDO.GREATER_EQUAL, 1.0, "c0");
57
58                MDOLinExpr tempLinExpr2 = new MDOLinExpr();
59                tempLinExpr2.AddTerms(consV[1], x);
60                model.AddConstr(tempLinExpr2, MDO.EQUAL, 1.0, "c1");

问题输入完成后,再调用 MDOModel.Optimize 求解优化问题:

63                model.Optimize();

求解完成后,用 MDOModel.Get 和模型属性值 ObjVal 来查看优化结果和最优目标值,以及 MDOVar.Get 和变量属性值 X 来查看优化解的目标值。 其他的属性值请查看 属性 章节。

65                if (model.Get(MDO.IntAttr.Status) == MDO.Status.OPTIMAL)
66                {
67                    Console.WriteLine($"Optimal objective value is: {model.Get(MDO.DoubleAttr.ObjVal)}");
68                    Console.WriteLine("Decision variables: ");
69                    for(int i = 0; i < 4; i++)
70                        Console.WriteLine($"x[{i}] = {x[i].Get(MDO.DoubleAttr.X)}");
71                }
72                else
73                {
74                    Console.WriteLine("No feasible solution.");
75                }

示例 MdoMiloEx1.cs 提供了完整源代码:

 1/**
 2 *  Description
 3 *  -----------
 4 *  Mixed Integer Linear optimization (row-wise input).
 5 *
 6 *  Formulation
 7 *  -----------
 8 *  Minimize
 9 *    obj: 1 x0 + 2 x1 + 1 x2 + 1 x3
10 *  Subject To
11 *   c0 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
12 *   c1 : 1 x0 - 1 x2 + 6 x3 = 1
13 *  Bounds
14 *    0 <= x0 <= 10
15 *    0 <= x1
16 *    0 <= x2
17 *    0 <= x3
18 *  Integers
19 *    x0 x1 x2
20 *  End
21 */
22 
23using Mindopt;
24
25namespace Example
26{
27    public class MdoMiloEx1
28    {
29        public static void Main(string[] args)
30        {
31            // Create model
32            MDOEnv env = new MDOEnv(); 
33            MDOModel model = new MDOModel(env); 
34            model.Set(MDO.StringAttr.ModelName, "MILP_01");
35
36            try
37            {
38                // Change to minimization problem.
39                model.Set(MDO.IntAttr.ModelSense, MDO.MINIMIZE);
40
41                // Add variables.
42                MDOVar[] x = new MDOVar[4];
43                x[0] = model.AddVar(0.0,         10.0, 1.0, 'I', "x0");
44                x[1] = model.AddVar(0.0, MDO.INFINITY, 2.0, 'I', "x1");
45                x[2] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'I', "x2");
46                x[3] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x3");
47
48                // Add constraints.
49                double[][] consV = new double[][]{
50                    new double[] { 1.0, 1.0, 2.0, 3.0},
51                    new double[] { 1.0, 0,  -1.0, 6.0} 
52                };
53
54                MDOLinExpr tempLinExpr1 = new MDOLinExpr();
55                tempLinExpr1.AddTerms(consV[0], x);
56                model.AddConstr(tempLinExpr1, MDO.GREATER_EQUAL, 1.0, "c0");
57
58                MDOLinExpr tempLinExpr2 = new MDOLinExpr();
59                tempLinExpr2.AddTerms(consV[1], x);
60                model.AddConstr(tempLinExpr2, MDO.EQUAL, 1.0, "c1");
61        
62                // Solve the problem and populate the result.
63                model.Optimize();
64
65                if (model.Get(MDO.IntAttr.Status) == MDO.Status.OPTIMAL)
66                {
67                    Console.WriteLine($"Optimal objective value is: {model.Get(MDO.DoubleAttr.ObjVal)}");
68                    Console.WriteLine("Decision variables: ");
69                    for(int i = 0; i < 4; i++)
70                        Console.WriteLine($"x[{i}] = {x[i].Get(MDO.DoubleAttr.X)}");
71                }
72                else
73                {
74                    Console.WriteLine("No feasible solution.");
75                }
76            }
77            catch (Exception e)
78            { 
79                Console.WriteLine("Exception during optimization");
80                Console.WriteLine(e.Message);
81            }
82            finally
83            { 
84                model.Dispose();
85                env.Dispose();
86            }
87        }
88    }
89}