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.Set
和 MDOModel.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}