5.1.4. Modeling and optimization in Python¶
This topic describes how to use the Python API of MindOpt to build a model and solve the problem in Examples of linear programming problems.
5.1.4.1. Input by row: mdo_lo_ex1¶
Load the Python package.
24from mindoptpy import *
Create an optimization model.
31 # Step 1. Create a model and change the parameters.
32 model = MdoModel()
Call mindoptpy.MdoModel.set_int_attr()
to set the target function to Minimization, call mindoptpy.MdoModel.add_var()
to add four optimization variables, and define the upper bound, lower bound, names, and types of the variables. For more information about how to use mindoptpy.MdoModel.set_int_attr()
and mindoptpy.MdoModel.add_var()
, see Python API.
35 # Step 2. Input model.
36 # Change to minimization problem.
37 model.set_int_attr(MDO_INT_ATTR.MIN_SENSE, 1)
38
39 # Add variables.
40 x = []
41 x.append(model.add_var(0.0, 10.0, 1.0, None, "x0", False))
42 x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x1", False))
43 x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x2", False))
44 x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x3", False))
Add linear constraints.
46 # Add constraints.
47 # Note that the nonzero elements are inputted in a row-wise order here.
48 model.add_cons(1.0, MDO_INFINITY, 1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3], "c0")
49 model.add_cons(1.0, 1.0, 1.0 * x[0] - 1.0 * x[2] + 6.0 * x[3], "c1")
Call mindoptpy.MdoModel.solve_prob()
to solve the optimization problem, and call mindoptpy.MdoModel.display_results()
to view the optimization result.
51 # Step 3. Solve the problem and populate the result.
52 model.solve_prob()
53 model.display_results()
Call mindoptpy.MdoModel.free_mdl()
to release the memory.
63 # Step 4. Free the model.
64 model.free_mdl()
The linked file mdo_lo_ex1.py provides complete source code:
1"""
2/**
3 * Description
4 * -----------
5 *
6 * Linear optimization (row-wise input).
7 *
8 * Formulation
9 * -----------
10 *
11 * Minimize
12 * obj: 1 x0 + 1 x1 + 1 x2 + 1 x3
13 * Subject To
14 * c1 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
15 * c2 : 1 x0 - 1 x2 + 6 x3 = 1
16 * Bounds
17 * 0 <= x0 <= 10
18 * 0 <= x1
19 * 0 <= x2
20 * 0 <= x3
21 * End
22 */
23"""
24from mindoptpy import *
25
26
27if __name__ == "__main__":
28
29 MDO_INFINITY = MdoModel.get_infinity()
30
31 # Step 1. Create a model and change the parameters.
32 model = MdoModel()
33
34 try:
35 # Step 2. Input model.
36 # Change to minimization problem.
37 model.set_int_attr(MDO_INT_ATTR.MIN_SENSE, 1)
38
39 # Add variables.
40 x = []
41 x.append(model.add_var(0.0, 10.0, 1.0, None, "x0", False))
42 x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x1", False))
43 x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x2", False))
44 x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x3", False))
45
46 # Add constraints.
47 # Note that the nonzero elements are inputted in a row-wise order here.
48 model.add_cons(1.0, MDO_INFINITY, 1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3], "c0")
49 model.add_cons(1.0, 1.0, 1.0 * x[0] - 1.0 * x[2] + 6.0 * x[3], "c1")
50
51 # Step 3. Solve the problem and populate the result.
52 model.solve_prob()
53 model.display_results()
54
55 except MdoError as e:
56 print("Received Mindopt exception.")
57 print(" - Code : {}".format(e.code))
58 print(" - Reason : {}".format(e.message))
59 except Exception as e:
60 print("Received exception.")
61 print(" - Reason : {}".format(e))
62 finally:
63 # Step 4. Free the model.
64 model.free_mdl()
5.1.4.2. Input by column: mdo_lo_ex2¶
In the following code, a model is built for the preceding problem, but non-zero elements of the matrix are sorted by column and then input.
If you input only the lower bound and upper bound of constraints when you call mindoptpy.MdoModel.add_cons()
, the constraint matrix is empty (without non-zero elements). After inputting constraints, create a column object mindoptpy.MdoCol()
to store the positions (indexes) and non-zero values of non-zero elements corresponding to the constraints in this column. Call mindoptpy.MdoModel.add_var()
to create a variable, and specify the target function coefficient, upper and lower bounds, as well as non-zero element, variable name, and variable type corresponding to each constraint in this column.
Call mindoptpy.MdoModel.get_status()
to check the optimization status of the solver, and call mindoptpy.MdoModel.get_real_attr()
and mindoptpy.MdoVar.get_real_attr()
to obtain the target value and optimal solution. For more information about how to use mindoptpy.MdoModel.get_real_attr()
and mindoptpy.MdoVar.get_real_attr()
, see Python API.
The linked file mdo_lo_ex2.py provides complete source code:
1"""
2/**
3 * Description
4 * -----------
5 *
6 * Linear optimization (column-wise input).
7 *
8 * Formulation
9 * -----------
10 *
11 * Minimize
12 * obj: 1 x0 + 1 x1 + 1 x2 + 1 x3
13 * Subject To
14 * c1 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
15 * c2 : 1 x0 - 1 x2 + 6 x3 = 1
16 * Bounds
17 * 0 <= x0 <= 10
18 * 0 <= x1
19 * 0 <= x2
20 * 0 <= x3
21 * End
22 */
23"""
24from mindoptpy import *
25
26
27if __name__ == "__main__":
28
29 MDO_INFINITY = MdoModel.get_infinity()
30
31 # Step 1. Create a model and change the parameters.
32 model = MdoModel()
33
34 try:
35 # Step 2. Input model.
36 # Change to minimization problem.
37 model.set_int_attr(MDO_INT_ATTR.MIN_SENSE, 1)
38
39 # Add empty constraints.
40 cons = []
41 cons.append(model.add_cons(1.0, MDO_INFINITY, None, "c0"))
42 cons.append(model.add_cons(1.0, 1.0, None, "c1"))
43
44 # Input columns.
45 col = []
46 for j in range(4):
47 col.append(MdoCol())
48 col[0].add_term(cons[0], 1.0)
49 col[0].add_term(cons[1], 1.0)
50 col[1].add_term(cons[0], 1.0)
51 col[2].add_term(cons[0], 2.0)
52 col[2].add_term(cons[1], -1.0)
53 col[3].add_term(cons[0], 3.0)
54 col[3].add_term(cons[1], 6.0)
55
56 # Add variables.
57 # Note that the nonzero elements are inputted in a column-wise order here.
58 x = []
59 x.append(model.add_var(0.0, 10.0, 1.0, col[0], "x0", False))
60 x.append(model.add_var(0.0, MDO_INFINITY, 1.0, col[1], "x1", False))
61 x.append(model.add_var(0.0, MDO_INFINITY, 1.0, col[2], "x2", False))
62 x.append(model.add_var(0.0, MDO_INFINITY, 1.0, col[3], "x3", False))
63
64 # Step 3. Solve the problem and populate the result.
65 model.solve_prob()
66 model.display_results()
67
68 status_code, status_msg = model.get_status()
69 if status_msg == "OPTIMAL":
70 print("Optimizer terminated with an OPTIMAL status (code {0}).".format(status_code))
71 print("Primal objective : {0}".format(round(model.get_real_attr(MDO_REAL_ATTR.PRIMAL_OBJ_VAL), 2)))
72 for curr_x in x:
73 print(" - x[{0}] : {1}".format(curr_x.get_index(), round(curr_x.get_real_attr(MDO_REAL_ATTR.PRIMAL_SOLN), 2)))
74 else:
75 print("Optimizer terminated with a(n) {0} status (code {1}).".format(status_msg, status_code))
76
77 except MdoError as e:
78 print("Received Mindopt exception.")
79 print(" - Code : {}".format(e.code))
80 print(" - Reason : {}".format(e.message))
81 except Exception as e:
82 print("Received exception.")
83 print(" - Explanation : {}".format(e))
84 finally:
85 # Step 4. Free the model.
86 model.free_mdl()
5.1.4.3. Advanced example: mdo_lo_ex3¶
The following code shows how to use other advanced API examples, such as inputting data into a model, modifying a model, obtaining a basic solution, and performing a hot start. For more information about how to use the API, see API Reference.
The linked file mdo_lo_ex3.py provides complete source code:
1"""
2/**
3 * Description
4 * -----------
5 *
6 * Linear optimization (row-wise input).
7 *
8 * Formulation
9 * -----------
10 *
11 * Minimize
12 * obj: 1 x0 + 1 x1 + 1 x2 + 1 x3
13 * Subject To
14 * c1 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
15 * c2 : 1 x0 - 1 x2 + 6 x3 = 1
16 * Bounds
17 * 0 <= x0 <= 10
18 * 0 <= x1
19 * 0 <= x2
20 * 0 <= x3
21 * End
22 */
23"""
24from mindoptpy import *
25
26
27if __name__ == "__main__":
28
29 MDO_INFINITY = MdoModel.get_infinity()
30 WRITE_LP = True
31
32 # Step 1. Create a model and change the parameters.
33 model = MdoModel()
34
35 try:
36 # Step 2. Input model.
37 print("\nStep 2. Input model.\n")
38 # Change to minimization problem.
39 model.set_int_attr(MDO_INT_ATTR.MIN_SENSE, 1)
40
41 # Add variables.
42 xs = model.add_vars(4, lb=0, ub=MDO_INFINITY, obj=1.0, name="x")
43 x = [ value for key, value in xs.items() ]
44 x[0].set_real_attr(MDO_REAL_ATTR.UB, 10.0)
45
46 # Add constraints.
47 # Note that the nonzero elements are inputted in a row-wise order here.
48 conss = []
49 conss.append(model.add_cons(1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3] >= 1.0, "c0"))
50 conss.append(model.add_cons(1.0 * x[0] - 1.0 * x[2] + 6.0 * x[3] == 1.0, "c1"))
51
52 # Step 3. Solve the problem and populate the result.
53 print("\nStep 3. Solve the problem and populate the result.\n")
54 model.solve_prob()
55 model.display_results()
56 if WRITE_LP:
57 model.write_prob("Step3.lp");
58
59 # Step 4. Add another two variables and then resolve the problem.
60 print("\nStep 4. Add another two variables and then resolve the problem.\n")
61 # Input columns.
62 cols = [ MdoCol() for i in range(2) ]
63 cols[0].add_terms(conss, [ 1.0, 2.0 ])
64 cols[1].add_terms(conss, [ 3.4, 4.0 ])
65 y = []
66 y.append(model.add_var( 0.0, MDO_INFINITY, 1.0, cols[0], "y0", False))
67 y.append(model.add_var(-2.0, MDO_INFINITY, -1.0, cols[1], "y1", False))
68
69 # Solve the problem.
70 model.solve_prob()
71 model.display_results()
72 if WRITE_LP:
73 model.write_prob("Step4.lp");
74
75 # Step 5. Add another two constraints and then resolve the problem.
76 print("\nStep 5. Add another two constraints and then resolve the problem.\n")
77 bgn2 = [ 0, 3, 6 ]
78 indices2 = [
79 0, 1, 3,
80 0, 2, 3
81 ]
82 values2 = [
83 1.0, 1.0, -2.0,
84 1.0, -2.0, 6.0
85 ]
86
87 lhss2 = [ 0, 1 ]
88 rhss2 = [ 2, MDO_INFINITY ]
89
90 expr = [ MdoExprLinear() for i in range(2) ]
91 for i in range(2):
92 for e in range(bgn2[i], bgn2[i + 1]):
93 expr[i] += values2[e] * x[indices2[e]]
94
95 c2 = model.add_conss( [ expr[i] == [lhss2[i], rhss2[i]] for i in range(2) ] )
96 for key, value in c2.items():
97 conss.append(value)
98
99 # Solve the problem.
100 model.solve_prob()
101 model.display_results()
102 if WRITE_LP:
103 model.write_prob("Step5.lp");
104
105 # Step 6. Obtain optimal basis.
106 print("\nStep 6. Obtain optimal basis.\n")
107
108 # isFree = 0,
109 # basic = 1,
110 # atUpperBound = 2,
111 # atLowerBound = 3,
112 # superBasic = 4,
113 # isFixed = 5,
114 col_basis = []
115 row_basis = []
116 for var in x:
117 print("Basis status of variable {0} is {1}".format(var.get_index(), var.get_int_attr(MDO_INT_ATTR.COL_BASIS)))
118 col_basis.append(var.get_int_attr(MDO_INT_ATTR.COL_BASIS))
119 for var in y:
120 print("Basis status of variable {0} is {1}".format(var.get_index(), var.get_int_attr(MDO_INT_ATTR.COL_BASIS)))
121 col_basis.append(var.get_int_attr(MDO_INT_ATTR.COL_BASIS))
122 for cons in conss:
123 print("Basis status of constraint {0} is {1}".format(cons.get_index(), cons.get_int_attr(MDO_INT_ATTR.ROW_BASIS)))
124 row_basis.append(cons.get_int_attr(MDO_INT_ATTR.ROW_BASIS))
125
126 if WRITE_LP:
127 model.write_prob("Step6.lp");
128 model.write_soln("Step6.bas");
129
130 # Step 7. Warm-start Simplex.
131 print("\nStep 7. Warm-start Simplex.\n")
132
133 # Change the objective coefficients.
134 x[1].set_real_attr("Obj", 3.0);
135 x[2].set_real_attr("Obj", -3.0);
136
137 # Load the basis.
138 model.set_int_attr_array(MDO_INT_ATTR.ROW_BASIS, 0, row_basis);
139 model.set_int_attr_array(MDO_INT_ATTR.COL_BASIS, 0, col_basis);
140
141 # Solve the problem.
142 model.solve_prob()
143 model.display_results()
144 if WRITE_LP:
145 model.write_prob("Step7.lp");
146
147 # Step 8. Model query.
148 print("\nStep 8. Model query.\n")
149
150 # Query 1: Retrieve first constraint.
151 print("Query 1: Retrieve first constraint.")
152
153 temp_expr = model.get_expr_linear(conss[0])
154 print(temp_expr)
155
156 # Query 2: Retrieve second column.
157 print("Query 2: Retrieve second column.")
158
159 temp_col = model.get_col(x[1]);
160 print(temp_col)
161
162 except MdoError as e:
163 print("Received Mindopt exception.")
164 print(" - Code : {}".format(e.code))
165 print(" - Reason : {}".format(e.message))
166 except Exception as e:
167 print("Received exception.")
168 print(" - Reason : {}".format(e))
169 finally:
170 # Step 4. Free the model.
171 model.free_mdl()