5.5.4. MIQP Modeling and Optimization in PythonΒΆ
In this section, we will utilize MindOpt Python API to model and solve the problem in Example of Mixed Integer Quadratic Programming.
First of all, import MindOpt Python package:
27from mindoptpy import *
Create an optimization model model
:
33 model = Model("MIQP_01")
Next, we set the optimization sense to minimization via setting attribute ModelSense and
add four decision variables using Model.addVar()
(please refer to Attributes for the detailed usages of model attributes, and Python API for other Python API information):
36 # Step 2. Input model.
37
38 # Add variables.
39 x = []
40 x.append(model.addVar(0.0, 10.0, 0.0, 'I', "x0"))
41 x.append(model.addVar(0.0, float('inf'), 0.0, 'C', "x1"))
Next, we call Model.addConstr()
to input the linear constraints:
43 x.append(model.addVar(0.0, float('inf'), 0.0, 'C', "x3"))
44
45 # Add constraints.
46 # Note that the nonzero elements are inputted in a row-wise order here.
Then, we set the objective function. We first create a quadratic expression using the class QuadExpr
. There are two ways to construct it:
The first way is to use the method QuadExpr.addTerms()
in QuadExpr to input the linear part and quadratic part separately.
The second way is to directly input a quadratic expression.
Subsequently, we use Model.setObjective()
to set the objective function and set the problem to minimization.
49 model.addConstr(1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3] >= 1, "c0")
50 model.addConstr(1.0 * x[0] - 1.0 * x[2] + 6.0 * x[3] == 1, "c1")
51
52 # Add objective: 1 x0 + 1 x1 + 1 x2 + 1 x3 + 1/2 [ x0^2 + x1^2 + x2^2 + x3^2 + x0 x1]
53 obj = QuadExpr()
54
55 #option-I
56 obj.addTerms([1.0, 1.0, 1.0, 1.0], [x[0], x[1], x[2], x[3]])
57 obj.addTerms([0.5, 0.5, 0.5, 0.5, 0.5], [x[0], x[1], x[2], x[3], x[0]], [x[0], x[1], x[2], x[3], x[1]])
58
59 #option II
60 # obj = 1*x[0] + 1*x[1] + 1*x[2] + 1*x[3] + 0.5 * x[0]*x[0] + 0.5 * x[1]*x[1] + 0.5 * x[2]*x[2] + 0.5 * x[3]*x[3] + 0.5*x[0]*x[1]
61
Once the model is constructed, we call Model.optimize()
to solve the problem:
62
We can check the solution status via the attribute Status, and retrieve the optimal objective value and solutions via attributes ObjVal and X. For other attribute information, please check Attributes.
64 model.optimize()
65
66 if model.status == MDO.OPTIMAL:
67 print(f"Optimal objective value is: {model.objval}")
68 print("Decision variables:")
69 for v in x:
70 print(f"x[{v.VarName}] = {v.X}")
Finally, we free the model by calling Model.dispose()
.
80 finally:
The complete python code is shown in mdo_miqp_ex1.py:
1"""
2/**
3 * Description
4 * -----------
5 *
6 * Quadratuc optimization (row-wise input).
7 *
8 * Formulation
9 * -----------
10 *
11 * Minimize
12 * obj: 1 x0 + 1 x1 + 1 x2 + 1 x3
13 * + 1/2 [ x0^2 + x1^2 + x2^2 + x3^2 + x0 x1]
14 * Subject To
15 * c1 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
16 * c2 : 1 x0 - 1 x2 + 6 x3 = 1
17 * Bounds
18 * 0 <= x0 <= 10
19 * 0 <= x1
20 * 0 <= x2
21 * 0 <= x3
22 * Integers
23 * x0
24 * End
25 */
26"""
27from mindoptpy import *
28
29
30if __name__ == "__main__":
31
32 # Step 1. Create model.
33 model = Model("MIQP_01")
34
35 try:
36 # Step 2. Input model.
37
38 # Add variables.
39 x = []
40 x.append(model.addVar(0.0, 10.0, 0.0, 'I', "x0"))
41 x.append(model.addVar(0.0, float('inf'), 0.0, 'C', "x1"))
42 x.append(model.addVar(0.0, float('inf'), 0.0, 'C', "x2"))
43 x.append(model.addVar(0.0, float('inf'), 0.0, 'C', "x3"))
44
45 # Add constraints.
46 # Note that the nonzero elements are inputted in a row-wise order here.
47 model.addConstr(1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3] >= 1, "c0")
48 model.addConstr(1.0 * x[0] - 1.0 * x[2] + 6.0 * x[3] == 1, "c1")
49
50 # Add objective: 1 x0 + 1 x1 + 1 x2 + 1 x3 + 1/2 [ x0^2 + x1^2 + x2^2 + x3^2 + x0 x1]
51 obj = QuadExpr()
52
53 #option-I
54 obj.addTerms([1.0, 1.0, 1.0, 1.0], [x[0], x[1], x[2], x[3]])
55 obj.addTerms([0.5, 0.5, 0.5, 0.5, 0.5], [x[0], x[1], x[2], x[3], x[0]], [x[0], x[1], x[2], x[3], x[1]])
56
57 #option II
58 # obj = 1*x[0] + 1*x[1] + 1*x[2] + 1*x[3] + 0.5 * x[0]*x[0] + 0.5 * x[1]*x[1] + 0.5 * x[2]*x[2] + 0.5 * x[3]*x[3] + 0.5*x[0]*x[1]
59
60 # Set objective and change to minimization problem.
61 model.setObjective(obj, MDO.MINIMIZE)
62
63 # Step 3. Solve the problem and populate optimization result.
64 model.optimize()
65
66 if model.status == MDO.OPTIMAL:
67 print(f"Optimal objective value is: {model.objval}")
68 print("Decision variables:")
69 for v in x:
70 print(f"x[{v.VarName}] = {v.X}")
71 else:
72 print("No feasible solution.")
73 except MindoptError as e:
74 print("Received Mindopt exception.")
75 print(" - Code : {}".format(e.errno))
76 print(" - Reason : {}".format(e.message))
77 except Exception as e:
78 print("Received other exception.")
79 print(" - Reason : {}".format(e))
80 finally:
81 # Step 4. Free the model.
82 model.dispose()