5.1.6. C# 的LP建模与优化

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

首先,创建优化模型:

31            // Create model
32            MDOEnv env = new MDOEnv(); 
33            MDOModel model = new MDOModel(env); 
34            model.Set(MDO.StringAttr.ModelName, "LP_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, 'C', "x0");
44                x[1] = model.AddVar(0.0, MDO.INFINITY, 2.0, 'C', "x1");
45                x[2] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x2");
46                x[3] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x3");

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

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

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

63                // Solve the problem and populate optimization result.
64                model.Optimize();

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

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

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

 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 
23using Mindopt;
24
25namespace Example
26{
27    public class MdoLoEx1
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, "LP_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, 'C', "x0");
44                x[1] = model.AddVar(0.0, MDO.INFINITY, 2.0, 'C', "x1");
45                x[2] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x2");
46                x[3] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x3");
47
48                // Add constraints.
49                double[][] consV = new double[][]
50                {
51                    new double[] { 1.0, 1.0, 2.0, 3.0},
52                    new double[] { 1.0, 0,  -1.0, 6.0} 
53                };
54
55                MDOLinExpr tempLinExpr1 = new MDOLinExpr();
56                tempLinExpr1.AddTerms(consV[0], x);
57                model.AddConstr(tempLinExpr1, MDO.GREATER_EQUAL, 1.0, "c0");
58
59                MDOLinExpr tempLinExpr2 = new MDOLinExpr();
60                tempLinExpr2.AddTerms(consV[1], x);
61                model.AddConstr(tempLinExpr2, MDO.EQUAL, 1.0, "c1");    
62        
63                // Solve the problem and populate optimization result.
64                model.Optimize();
65
66                if (model.Get(MDO.IntAttr.Status) == MDO.Status.OPTIMAL)
67                {
68                    Console.WriteLine($"Optimal objective value is: {model.Get(MDO.DoubleAttr.ObjVal)}");
69                    Console.WriteLine("Decision variables: ");
70                    for (int i = 0; i < 4; i++)
71                        Console.WriteLine( $"x[{i}] = {x[i].Get(MDO.DoubleAttr.X)}");
72                }
73                else
74                {
75                    Console.WriteLine("No feasible solution.");
76                }
77            }
78            catch (Exception e)
79            { 
80                Console.WriteLine("Exception during optimization");
81                Console.WriteLine(e.Message);
82            }
83            finally
84            { 
85                model.Dispose();
86                env.Dispose();
87            }
88        }
89    }
90}