5.5.6. MIQP Modeling and Optimization in C#ΒΆ
In this chapter, we will use MindOpt C# API to model and solve the problem in Example of Mixed Integer Quadratic Programming.
Create an optimization model model
:
32 // Create model
33 MDOEnv env = new MDOEnv();
34 MDOModel model = new MDOModel(env);
35 model.Set(MDO.StringAttr.ModelName, "MIQP_01");
Next, we set the optimization sense to minimization via MDOModel.Set
. Then, we call MDOModel.AddVar
to add four variables, which define upper bounds, lower bounds, names and types.
(for more details on MDOModel.Set
and MDOModel.AddVar
, please refer to C# API)
42 // Add variables.
43 MDOVar[] x = new MDOVar[4];
44 x[0] = model.AddVar(0.0, 10.0, 1.0, 'I', "x0");
45 x[1] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x1");
46 x[2] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x2");
47 x[3] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x3");
We input the linear constraints into model
:
49 // Add constraints.
50 double[][] consV = new double[][]
51 {
52 new double[] { 1.0, 1.0, 2.0, 3.0},
53 new double[] { 1.0, 0, -1.0, 6.0}
54 };
55
56 MDOLinExpr tempLinExpr1 = new MDOLinExpr();
57 tempLinExpr1.AddTerms(consV[0], x);
58 model.AddConstr(tempLinExpr1, MDO.GREATER_EQUAL, 1.0, "c0");
59
60 MDOLinExpr tempLinExpr2 = new MDOLinExpr();
61 tempLinExpr2.AddTerms(consV[1], x);
62 model.AddConstr(tempLinExpr2, MDO.EQUAL, 1.0, "c1");
Then, we create a quadratic expression MDOQuadExpr
and call MDOQuadExpr.AddTerms
to set the linear part of the objective function. Here obj_idx
represents the indices of the linear terms, obj_val
represents the corresponding non-zero coefficient values in obj_idx
.
64 // Create a QuadExpr for quadratic objective
65 MDOQuadExpr obj = new MDOQuadExpr();
66
67 // Add objective linear term: 1 x0 + 1 x1 + 1 x2 + 1 x3
68 int obj_nnz = 4;
69 MDOVar[] obj_idx = new MDOVar[] { x[0], x[1], x[2], x[3] };
70 double[] obj_val = new double[] { 1.0, 1.0, 1.0, 1.0 };
71 obj.AddTerms(obj_val, obj_idx);
We call MDOQuadExpr.AddTerms
to set the quadratic terms of the objective. Here, qo_values
represents the coefficients of all the non-zero quadratic terms, while qo_col1
and qo_col2
respectively represent its row and column indices.
73 // Add quadratic part in objective: 1/2 [ x0^2 + x1^2 + x2^2 + x3^2 + x0 x1]
74 int qo_nnz = 5;
75 MDOVar[] qo_col1 = new MDOVar[] { x[0], x[1], x[2], x[3], x[0] };
76 MDOVar[] qo_col2 = new MDOVar[] { x[0], x[1], x[2], x[3], x[1] };
77 double[] qo_values = new double[] { 0.5, 0.5, 0.5, 0.5, 0.5 };
78 obj.AddTerms(qo_values, qo_col1, qo_col2);
Lastly, we call MDOModel.SetObjective
to set the objective and the direction to be optimized.
80 model.SetObjective(obj, MDO.MINIMIZE);
Once the model is constructed, we call MDOModel.Optimize
to solve the problem:
83 model.Optimize();
The complete example code is shown in MdoMIQPEx1.cs :
1/**
2 * Description
3 * -----------
4 * Linear optimization (row-wise input).
5 *
6 * Formulation
7 * -----------
8 *
9 * Minimize
10 * obj: 1 x0 + 1 x1 + 1 x2 + 1 x3
11 * + 1/2 [ x0^2 + x1^2 + x2^2 + x3^2 + x0 x1]
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 * x0 Integer
21 * End
22 */
23
24using Mindopt;
25
26namespace Example
27{
28 public class MdoQoEx1
29 {
30 public static void Main(string[] args)
31 {
32 // Create model
33 MDOEnv env = new MDOEnv();
34 MDOModel model = new MDOModel(env);
35 model.Set(MDO.StringAttr.ModelName, "MIQP_01");
36
37 try
38 {
39 // Change to minimization problem.
40 model.Set(MDO.IntAttr.ModelSense, MDO.MINIMIZE);
41
42 // Add variables.
43 MDOVar[] x = new MDOVar[4];
44 x[0] = model.AddVar(0.0, 10.0, 1.0, 'I', "x0");
45 x[1] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x1");
46 x[2] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x2");
47 x[3] = model.AddVar(0.0, MDO.INFINITY, 1.0, 'C', "x3");
48
49 // Add constraints.
50 double[][] consV = new double[][]
51 {
52 new double[] { 1.0, 1.0, 2.0, 3.0},
53 new double[] { 1.0, 0, -1.0, 6.0}
54 };
55
56 MDOLinExpr tempLinExpr1 = new MDOLinExpr();
57 tempLinExpr1.AddTerms(consV[0], x);
58 model.AddConstr(tempLinExpr1, MDO.GREATER_EQUAL, 1.0, "c0");
59
60 MDOLinExpr tempLinExpr2 = new MDOLinExpr();
61 tempLinExpr2.AddTerms(consV[1], x);
62 model.AddConstr(tempLinExpr2, MDO.EQUAL, 1.0, "c1");
63
64 // Create a QuadExpr for quadratic objective
65 MDOQuadExpr obj = new MDOQuadExpr();
66
67 // Add objective linear term: 1 x0 + 1 x1 + 1 x2 + 1 x3
68 int obj_nnz = 4;
69 MDOVar[] obj_idx = new MDOVar[] { x[0], x[1], x[2], x[3] };
70 double[] obj_val = new double[] { 1.0, 1.0, 1.0, 1.0 };
71 obj.AddTerms(obj_val, obj_idx);
72
73 // Add quadratic part in objective: 1/2 [ x0^2 + x1^2 + x2^2 + x3^2 + x0 x1]
74 int qo_nnz = 5;
75 MDOVar[] qo_col1 = new MDOVar[] { x[0], x[1], x[2], x[3], x[0] };
76 MDOVar[] qo_col2 = new MDOVar[] { x[0], x[1], x[2], x[3], x[1] };
77 double[] qo_values = new double[] { 0.5, 0.5, 0.5, 0.5, 0.5 };
78 obj.AddTerms(qo_values, qo_col1, qo_col2);
79
80 model.SetObjective(obj, MDO.MINIMIZE);
81
82 // Solve the problem and populate optimization result.
83 model.Optimize();
84
85 if (model.Get(MDO.IntAttr.Status) == MDO.Status.OPTIMAL)
86 {
87 Console.WriteLine($"Optimal objective value is: {model.Get(MDO.DoubleAttr.ObjVal)}");
88 Console.WriteLine("Decision variables: ");
89 for (int i = 0; i < 4; i++)
90 Console.WriteLine( $"x[{i}] = {x[i].Get(MDO.DoubleAttr.X)}");
91 }
92 else
93 {
94 Console.WriteLine("No feasible solution.");
95 }
96 }
97 catch (Exception e)
98 {
99 Console.WriteLine("Exception during optimization");
100 Console.WriteLine(e.Message);
101 }
102 finally
103 {
104 model.Dispose();
105 env.Dispose();
106 }
107 }
108 }
109}