5.4. 约束不可行性分析¶
在对实际应用中的优化问题进行建模求解的过程中,往往会遇到问题不可行的情况。而不可行问题必然是由某些约束互相之间冲突导致的,如何分析问题的不可行性并识别出导致冲突的关键约束成为求解器应用的重要一环。
这类导致问题不可行的最小约束子集被称为不可约不可行系统 (IIS, irreduciable infeasible system)。MindOpt 设计了用来计算 IIS 的 API,用户可以通过利用该 API 来对不可行问题进行分析。再依据此对 IIS 中的约束进行修正或移除,可以使得优化问题变得可行,以便于更好地对实际问题进行分析建模和获得最优决策。
需要注意的是,在线性规划问题中,IIS 可能并不是唯一的。若存在多个 IIS,则需要对优化问题进行多次调整,才能使其变得可行。例如:
在这个例子中,我们很容易知道 \(c_1\) 与 \(c_2\) 为一组 IIS,\(c_3\) 与 \(c_4\) 为一组 IIS。在同时移除 \(c_1\) 或 \(c_2\) 中的任意一条约束以及 \(c_3\) 或 \(c_4\) 中的任意一条约束后,该问题将变得可行。
我们将通过一个更加实际的例子,来展示如何在 MindOpt 中使用约束不可行性分析来获取 IIS。考虑如下的不可行约束系统:
其中,前面三组约束构成一组IIS,而第四个约束和变量上下界则构成另外一组IIS。
Note
MindOpt 目前采用过滤算法来寻找IIS。过滤算法虽然能在短时间找出一组IIS,但无法保证IIS的规模是所有IIS组合中最小的。此外,若使用者对约束顺序做调整,则 MindOpt 也可能会产生不同的IIS。
Note
实际操作上,我们建议使用者修复IIS中的冲突后,再将修改后的模型输入至求解IIS的API,并修复下一个IIS;依此直至所有的冲突都得以修复。
接下来,我们将分别说明如何在 C/C++/Python 环境中应用 MindOpt 来获取不可行问题的 IIS。
5.4.1. C API: Mdo_computeIIS¶
首先,参考 C 语言的建模和优化 中的方法创建优化问题并设置参数:
94 /*------------------------------------------------------------------*/
95 /* Step 1. Create a model and change the parameters. */
96 /*------------------------------------------------------------------*/
97 printf(" Create a model and change the parameters.\n\n");
98 /* Create an empty model. */
99 MDO_CHECK_CALL(Mdo_createMdl(&model));
100 /* Turn-off the presolver so that solver won't terminate with an MDO_INF_OR_UBD status. */
101 MDO_CHECK_CALL(Mdo_setIntParam(model, MDO_INT_PARAM_PRESOLVE, 0));
102 /* Use dual-Simplex method. */
103 MDO_CHECK_CALL(Mdo_setIntParam(model, MDO_INT_PARAM_METHOD, 1));
104
105 /*------------------------------------------------------------------*/
106 /* Step 2. Input model. */
107 /*------------------------------------------------------------------*/
108 printf("\nStep 2. Input model.\n\n");
109 /* The following three input methods will all result in the same model. */
110 /* Change to minimization problem. */
111 MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
112
113 /* Add variables. */
114 for (i = 0; i < 5; ++i)
115 {
116 MDO_CHECK_CALL(Mdo_addCol(model, lbs[i], ubs[i], objs[i], 0, NULL, NULL, col_names[i], MDO_NO));
117 }
118 /* Add two constraints.
119 * The coefficients of the constraint matrix are inputted in a row-wise order.
120 */
121 MDO_CHECK_CALL(Mdo_addRows(model, 7, lhss, rhss, csr_bgn, csr_indices, csr_values, row_names));
接下来,当优化问题不可行时,使用 Mdo_computeIIS()
获取不可约不可行子系统的行列坐标,并打印对应的约束名与变量名:
140 case MDO_INFEASIBLE:
141 printf("Optimizer terminated with an INFEASIBLE status.\n");
142 printf("Compute IIS.\n");
143 MDO_CHECK_CALL(Mdo_computeIIS(model, &num_iis_rows, idx_iis_rows, &num_iis_cols, idx_iis_cols));
144 printf("Computed IIS has %d rows and %d columns.\n", num_iis_rows, num_iis_cols);
145 printf("Populating IIS.\n");
146 for (i = 0; i < num_iis_rows; ++i)
147 {
148 char row_name_iis[1024] = { "\0" };
149 Mdo_getRowName(model, idx_iis_rows[i], row_name_iis, 1024, NULL);
150 printf(" Constraint: %s\n", row_name_iis);
151 }
152 for (j = 0; j < num_iis_cols; ++j)
153 {
154 char col_name_iis[1024] = { "\0" };
155 Mdo_getColName(model, idx_iis_cols[j], col_name_iis, 1024, NULL);
156 printf(" Variable: %10d\n", col_name_iis);
157 }
158 break;
MdoLoIIS.c 提供了完整源代码:
1/**
2 * Description
3 * -----------
4 *
5 * Linear optimization.
6 * - Compute IIS of an infeasible problem.
7 *
8 * Formulation
9 * -----------
10 *
11 * Minimize
12 * Obj:
13 * Subject To
14 * c0: -0.500000000 x0 + x1 >= 0.500000000
15 * c1: 2 x0 - x1 >= 3
16 * c2: 3 x0 + x1 <= 6
17 * c3: 3 x3 - x4 <= 2 <- conflicts with variable bounds!
18 * c4: x0 + x4 <= 10
19 * c5: x0 + 2 x1 + x3 <= 14
20 * c6: x1 + x3 >= 1
21 * Bounds
22 * 5 <= x3
23 * 0 <= x4 <= 2
24 * End
25 */
26#include <stdio.h>
27#include <stdlib.h>
28#include "Mindopt.h"
29
30
31/* Macro to check the return code */
32#define MDO_CHECK_CALL(MDO_CALL) \
33 code = MDO_CALL; \
34 if (code != MDO_OKAY) \
35 { \
36 Mdo_explainResult(model, code, str); \
37 Mdo_freeMdl(&model); \
38 fprintf(stderr, "===================================\n"); \
39 fprintf(stderr, "Error : code <%d>\n", code); \
40 fprintf(stderr, "Reason : %s\n", str); \
41 fprintf(stderr, "===================================\n"); \
42 return (int)code; \
43 }
44
45int main(void)
46{
47 /* Variables. */
48 char str[1024] = { "\0" };
49 MdoMdl * model = NULL;
50 MdoResult code = MDO_OKAY;
51 MdoStatus status = MDO_UNKNOWN;
52 double val;
53 int num_iis_rows, num_iis_cols;
54 int idx_iis_rows[7], idx_iis_cols[5];
55 int i, j;
56
57 const int csr_bgn[] = {0, 2, 4, 6, 8, 10, 13, 15};
58 const int csr_indices[] =
59 {
60 0, 1,
61 0, 1,
62 0, 1,
63 3, 4,
64 0, 4,
65 0, 1, 3,
66 1, 3
67 };
68 const double csr_values[] =
69 {
70 -0.5, 1,
71 2, -1,
72 3, 1,
73 3, -1,
74 1, 1,
75 1, 2, 1,
76 1, 1
77 };
78
79 const double lhss[] =
80 {
81 0.5, 3.0, -MDO_INFINITY, -MDO_INFINITY, -MDO_INFINITY, -MDO_INFINITY, 1.0
82 };
83 const double rhss[] =
84 {
85 MDO_INFINITY, MDO_INFINITY, 6.0, 2.0, 10.0, 14.0, MDO_INFINITY
86 };
87 const char* row_names[] = { "c0", "c1" , "c2" , "c3" , "c4" , "c5" , "c6" };
88
89 const double lbs[] = { 0.0, 0.0, 0.0, 5.0, 0.0 };
90 const double ubs[] = { MDO_INFINITY, MDO_INFINITY, MDO_INFINITY, MDO_INFINITY, 2.0 };
91 const double objs[] = { 0.0, 0.0, 0.0, 0.0, 0.0 };
92 const char* col_names[] = { "x0", "x1", "x2", "x3", "x4" };
93
94 /*------------------------------------------------------------------*/
95 /* Step 1. Create a model and change the parameters. */
96 /*------------------------------------------------------------------*/
97 printf(" Create a model and change the parameters.\n\n");
98 /* Create an empty model. */
99 MDO_CHECK_CALL(Mdo_createMdl(&model));
100 /* Turn-off the presolver so that solver won't terminate with an MDO_INF_OR_UBD status. */
101 MDO_CHECK_CALL(Mdo_setIntParam(model, MDO_INT_PARAM_PRESOLVE, 0));
102 /* Use dual-Simplex method. */
103 MDO_CHECK_CALL(Mdo_setIntParam(model, MDO_INT_PARAM_METHOD, 1));
104
105 /*------------------------------------------------------------------*/
106 /* Step 2. Input model. */
107 /*------------------------------------------------------------------*/
108 printf("\nStep 2. Input model.\n\n");
109 /* The following three input methods will all result in the same model. */
110 /* Change to minimization problem. */
111 MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
112
113 /* Add variables. */
114 for (i = 0; i < 5; ++i)
115 {
116 MDO_CHECK_CALL(Mdo_addCol(model, lbs[i], ubs[i], objs[i], 0, NULL, NULL, col_names[i], MDO_NO));
117 }
118 /* Add two constraints.
119 * The coefficients of the constraint matrix are inputted in a row-wise order.
120 */
121 MDO_CHECK_CALL(Mdo_addRows(model, 7, lhss, rhss, csr_bgn, csr_indices, csr_values, row_names));
122
123 /*------------------------------------------------------------------*/
124 /* Step 3. Solve the problem and populate the result. */
125 /*------------------------------------------------------------------*/
126 printf("\nStep 3. Solve the problem and populate the result.\n\n");
127 /* Solve the problem. */
128 MDO_CHECK_CALL(Mdo_solveProb(model));
129 Mdo_displayResults(model);
130
131 switch (Mdo_getStatus(model))
132 {
133 case MDO_UNKNOWN:
134 printf("Optimizer terminated with an UNKNOWN status.\n");
135 break;
136 case MDO_OPTIMAL:
137 MDO_CHECK_CALL(Mdo_getRealAttr(model, MDO_REAL_ATTR_PRIMAL_OBJ_VAL, &val));
138 printf("Optimizer terminated with an OPTIMAL status.\n");
139 printf(" - Primal objective : %e.\n", val);
140 break;
141 case MDO_INFEASIBLE:
142 printf("Optimizer terminated with an INFEASIBLE status.\n");
143 printf("Compute IIS.\n");
144 MDO_CHECK_CALL(Mdo_computeIIS(model, &num_iis_rows, idx_iis_rows, &num_iis_cols, idx_iis_cols));
145 printf("Computed IIS has %d rows and %d columns.\n", num_iis_rows, num_iis_cols);
146 printf("Populating IIS.\n");
147 for (i = 0; i < num_iis_rows; ++i)
148 {
149 char row_name_iis[1024] = { "\0" };
150 Mdo_getRowName(model, idx_iis_rows[i], row_name_iis, 1024, NULL);
151 printf(" Constraint: %s\n", row_name_iis);
152 }
153 for (j = 0; j < num_iis_cols; ++j)
154 {
155 char col_name_iis[1024] = { "\0" };
156 Mdo_getColName(model, idx_iis_cols[j], col_name_iis, 1024, NULL);
157 printf(" Variable: %10d\n", col_name_iis);
158 }
159 break;
160 case MDO_UNBOUNDED:
161 printf("Optimizer terminated with an UNBOUNDED status.\n");
162 break;
163 case MDO_INF_OR_UBD:
164 printf("Optimizer terminated with an INFEASIBLE or UNBOUNDED status.\n");
165 break;
166 }
167
168 /*------------------------------------------------------------------*/
169 /* Step 4. Free the model. */
170 /*------------------------------------------------------------------*/
171 printf("\nStep 4. Free the model.\n");
172 /* Free the model. */
173 Mdo_freeMdl(&model);
174
175 return (int)code;
176}
5.4.2. C++ API:computeIIS¶
首先,参考 C++ 的建模和优化 中的方法创建优化问题并设置参数:
52 model.setIntAttr(MDO_INT_ATTR::MIN_SENSE, MDO_YES);
53
54 /* Add variables. */
55 std::vector<MdoVar> x;
56 x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, "x0", MDO_NO));
57 x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, "x1", MDO_NO));
58 x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, "x2", MDO_NO));
59 x.push_back(model.addVar(5.0, MDO_INFINITY, 0.0, "x3", MDO_NO));
60 x.push_back(model.addVar(0.0, 2.0, 0.0, "x4", MDO_NO));
61
62 /* Add constraints. */
63 model.addCons(-0.5 * x[0] + x[1] >= 0.5, "c0");
64 model.addCons( 2.0 * x[0] - x[1] >= 3.0, "c1");
65 model.addCons( 3.0 * x[0] + x[1] <= 6.0, "c2");
66 model.addCons( 3.0 * x[3] - x[4] <= 2.0, "c3");
67 model.addCons( x[0] + x[4] <= 10.0, "c4");
68 model.addCons( x[0] + 2.0 * x[1] + x[3] <= 14.0, "c5");
69 model.addCons( x[1] + x[3] >= 1.0, "c6");
接下来,当优化问题不可行时,使用 mindopt::MdoModel::computeIIS()
获取不可约不可行子系统的行列坐标,并打印对应的约束名与变量名:
86 case MDO_INFEASIBLE:
87 std::cout << "Optimizer terminated with an INFEASIBLE status." << std::endl;
88 std::cout << "Compute IIS." << std::endl;
89 model.computeIIS(idx_rows, idx_cols);
90
91 std::cout << "Computed IIS has " << idx_rows.size() << " rows and " << idx_cols.size() << " columns." << std::endl;
92 std::cout << "Populating IIS." << std::endl;
93 for (int i : idx_rows)
94 {
95 std::cout << "Constraint: " << model.getStrAttrIndex("RowName", i) << std::endl;
96 }
97 for (int j : idx_cols)
98 {
99 std::cout << "Variable: " << model.getStrAttrIndex("ColName", j) << std::endl;
100 }
101 break;
MdoLoIIS.cpp 提供了完整源代码:
1/**
2 * Description
3 * -----------
4 *
5 * Linear optimization.
6 * - Compute IIS of an infeasible problem.
7 *
8 * Formulation
9 * -----------
10 *
11 * Minimize
12 * Obj:
13 * Subject To
14 * c0: -0.500000000 x0 + x1 >= 0.500000000
15 * c1: 2 x0 - x1 >= 3
16 * c2: 3 x0 + x1 <= 6
17 * c3: 3 x3 - x4 <= 2 <- conflicts with variable bounds!
18 * c4: x0 + x4 <= 10
19 * c5: x0 + 2 x1 + x3 <= 14
20 * c6: x1 + x3 >= 1
21 * Bounds
22 * 5 <= x3
23 * 0 <= x4 <= 2
24 * End
25 */
26#include <iostream>
27#include <vector>
28#include "MindoptCpp.h"
29
30using namespace mindopt;
31
32int main(void)
33{
34 std::vector<int> idx_rows, idx_cols;
35
36 /*------------------------------------------------------------------*/
37 /* Step 1. Create a model and change the parameters. */
38 /*------------------------------------------------------------------*/
39 /* Create an empty model. */
40 MdoModel model;
41 /* Turn-off the presolver so that solver won't terminate with an MDO_INF_OR_UBD status. */
42 model.setIntParam(MDO_INT_PARAM::PRESOLVE, 0);
43 /* Use dual-Simplex method. */
44 model.setIntParam(MDO_INT_PARAM::METHOD, 1);
45
46 try
47 {
48 /*------------------------------------------------------------------*/
49 /* Step 2. Input model. */
50 /*------------------------------------------------------------------*/
51 /* Change to minimization problem. */
52 model.setIntAttr(MDO_INT_ATTR::MIN_SENSE, MDO_YES);
53
54 /* Add variables. */
55 std::vector<MdoVar> x;
56 x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, "x0", MDO_NO));
57 x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, "x1", MDO_NO));
58 x.push_back(model.addVar(0.0, MDO_INFINITY, 0.0, "x2", MDO_NO));
59 x.push_back(model.addVar(5.0, MDO_INFINITY, 0.0, "x3", MDO_NO));
60 x.push_back(model.addVar(0.0, 2.0, 0.0, "x4", MDO_NO));
61
62 /* Add constraints. */
63 model.addCons(-0.5 * x[0] + x[1] >= 0.5, "c0");
64 model.addCons( 2.0 * x[0] - x[1] >= 3.0, "c1");
65 model.addCons( 3.0 * x[0] + x[1] <= 6.0, "c2");
66 model.addCons( 3.0 * x[3] - x[4] <= 2.0, "c3");
67 model.addCons( x[0] + x[4] <= 10.0, "c4");
68 model.addCons( x[0] + 2.0 * x[1] + x[3] <= 14.0, "c5");
69 model.addCons( x[1] + x[3] >= 1.0, "c6");
70
71 /*------------------------------------------------------------------*/
72 /* Step 3. Solve the problem and populate the result. */
73 /*------------------------------------------------------------------*/
74 /* Solve the problem. */
75 model.solveProb();
76 model.displayResults();
77
78 switch (model.getStatus())
79 {
80 case MDO_UNKNOWN:
81 std::cout << "Optimizer terminated with an UNKNOWN status." << std::endl;
82 break;
83 case MDO_OPTIMAL:
84 std::cout << "Optimizer terminated with an OPTIMAL status." << std::endl;
85 break;
86 case MDO_INFEASIBLE:
87 std::cout << "Optimizer terminated with an INFEASIBLE status." << std::endl;
88 std::cout << "Compute IIS." << std::endl;
89 model.computeIIS(idx_rows, idx_cols);
90
91 std::cout << "Computed IIS has " << idx_rows.size() << " rows and " << idx_cols.size() << " columns." << std::endl;
92 std::cout << "Populating IIS." << std::endl;
93 for (int i : idx_rows)
94 {
95 std::cout << "Constraint: " << model.getStrAttrIndex("RowName", i) << std::endl;
96 }
97 for (int j : idx_cols)
98 {
99 std::cout << "Variable: " << model.getStrAttrIndex("ColName", j) << std::endl;
100 }
101 break;
102 case MDO_UNBOUNDED:
103 std::cout << "Optimizer terminated with an UNBOUNDED status." << std::endl;
104 break;
105 case MDO_INF_OR_UBD:
106 std::cout << "Optimizer terminated with an INFEASIBLE or UNBOUNDED status." << std::endl;
107 break;
108 }
109 }
110 catch (MdoException & e)
111 {
112 std::cerr << "===================================" << std::endl;
113 std::cerr << "Error : code <" << e.getResult() << ">" << std::endl;
114 std::cerr << "Reason : " << model.explainResult(e.getResult()) << std::endl;
115 std::cerr << "===================================" << std::endl;
116
117 return static_cast<int>(e.getResult());
118 }
119
120 return static_cast<int>(MDO_OKAY);
121}
5.4.3. Python API: compute_iis¶
首先,参考 Python 的建模与优化 中的方法创建优化问题并设置参数:
42 # Step 2. Input model.
43 # Change to minimization problem.
44 model.set_int_attr(MDO_INT_ATTR.MIN_SENSE, 1)
45
46 # Add variables.
47 # Note that the nonzero elements are inputted in a column-wise order here.
48 x = []
49 x.append(model.add_var(0.0, MDO_INFINITY, 0.0, None, "x0", False))
50 x.append(model.add_var(0.0, MDO_INFINITY, 0.0, None, "x1", False))
51 x.append(model.add_var(0.0, MDO_INFINITY, 0.0, None, "x2", False))
52 x.append(model.add_var(5.0, MDO_INFINITY, 0.0, None, "x3", False))
53 x.append(model.add_var(0.0, 2.0, 0.0, None, "x4", False))
54
55 # Add constraints.
56 # Note that the nonzero elements are inputted in a row-wise order here.
57 conss = []
58 conss.append(model.add_cons(-0.5 * x[0] + x[1] >= 0.5, "c0"))
59 conss.append(model.add_cons( 2.0 * x[0] - x[1] >= 3.0, "c1"))
60 conss.append(model.add_cons( 3.0 * x[0] + x[1] <= 6.0, "c2"))
61 conss.append(model.add_cons( 3.0 * x[3] - x[4] <= 2.0, "c3"))
62 conss.append(model.add_cons( x[0] + x[4] <= 10.0, "c4"))
63 conss.append(model.add_cons( x[0] + 2.0 * x[1] + x[3] <= 14.0, "c5"))
64 conss.append(model.add_cons( x[1] + x[3] >= 1.0, "c6"))
接下来,当优化问题不可行时,使用 mindoptpy.MdoModel.compute_iis()
获取不可约不可行子系统的行列坐标,并打印对应的约束名与变量名:
70 status_code, status_msg = model.get_status()
71 if status_msg == "INFEASIBLE":
72 print("Optimizer terminated with an MDO_INFEASIBLE status (code {0}).".format(status_code))
73 print("Compute IIS.")
74 idx_rows, idx_cols = model.compute_iis()
75
76 print("Computed IIS has {0} rows and {1} columns.".format(len(idx_rows), len(idx_cols)))
77 print("Populating IIS.")
78 for i in idx_rows:
79 print("Constraint: {0}".format(conss[i].get_str_attr("RowName")))
80 for j in idx_cols:
81 print("Variable: {0}".format(x[j].get_str_attr("ColName")))
mdo_lo_iis.py 提供了完整源代码:
1"""
2/**
3 * Description
4 * -----------
5 *
6 * Linear optimization.
7 * - Compute IIS of an infeasible problem.
8 *
9 * Formulation
10 * -----------
11 *
12 * Minimize
13 * Obj:
14 * Subject To
15 * c0: -0.500000000 x0 + x1 >= 0.500000000
16 * c1: 2 x0 - x1 >= 3
17 * c2: 3 x0 + x1 <= 6
18 * c3: 3 x3 - x4 <= 2 <- conflit with variable bounds below!
19 * c4: x0 + x4 <= 10
20 * c5: x0 + 2 x1 + x3 <= 14
21 * c6: x1 + x3 >= 1
22 * Bounds
23 * 5 <= x3
24 * 0 <= x4 <= 2
25 * End
26 */
27"""
28from mindoptpy import *
29
30
31if __name__ == "__main__":
32
33 MDO_INFINITY = MdoModel.get_infinity()
34
35 # Step 1. Create a model and change the parameters.
36 model = MdoModel()
37 # Turn-off the presolver so that solver won't terminate with an MDO_INF_OR_UBD status.
38 model.set_int_param(MDO_INT_PARAM.PRESOLVE, 0)
39 model.set_int_param(MDO_INT_PARAM.METHOD, 1)
40
41 try:
42 # Step 2. Input model.
43 # Change to minimization problem.
44 model.set_int_attr(MDO_INT_ATTR.MIN_SENSE, 1)
45
46 # Add variables.
47 # Note that the nonzero elements are inputted in a column-wise order here.
48 x = []
49 x.append(model.add_var(0.0, MDO_INFINITY, 0.0, None, "x0", False))
50 x.append(model.add_var(0.0, MDO_INFINITY, 0.0, None, "x1", False))
51 x.append(model.add_var(0.0, MDO_INFINITY, 0.0, None, "x2", False))
52 x.append(model.add_var(5.0, MDO_INFINITY, 0.0, None, "x3", False))
53 x.append(model.add_var(0.0, 2.0, 0.0, None, "x4", False))
54
55 # Add constraints.
56 # Note that the nonzero elements are inputted in a row-wise order here.
57 conss = []
58 conss.append(model.add_cons(-0.5 * x[0] + x[1] >= 0.5, "c0"))
59 conss.append(model.add_cons( 2.0 * x[0] - x[1] >= 3.0, "c1"))
60 conss.append(model.add_cons( 3.0 * x[0] + x[1] <= 6.0, "c2"))
61 conss.append(model.add_cons( 3.0 * x[3] - x[4] <= 2.0, "c3"))
62 conss.append(model.add_cons( x[0] + x[4] <= 10.0, "c4"))
63 conss.append(model.add_cons( x[0] + 2.0 * x[1] + x[3] <= 14.0, "c5"))
64 conss.append(model.add_cons( x[1] + x[3] >= 1.0, "c6"))
65
66 # Step 3. Solve the problem and populate the result.
67 model.solve_prob()
68 model.display_results()
69
70 status_code, status_msg = model.get_status()
71 if status_msg == "INFEASIBLE":
72 print("Optimizer terminated with an MDO_INFEASIBLE status (code {0}).".format(status_code))
73 print("Compute IIS.")
74 idx_rows, idx_cols = model.compute_iis()
75
76 print("Computed IIS has {0} rows and {1} columns.".format(len(idx_rows), len(idx_cols)))
77 print("Populating IIS.")
78 for i in idx_rows:
79 print("Constraint: {0}".format(conss[i].get_str_attr("RowName")))
80 for j in idx_cols:
81 print("Variable: {0}".format(x[j].get_str_attr("ColName")))
82 else:
83 print("Optimizer terminated with a(n) {0} status (code {1}).".format(status_msg, status_code))
84
85 except MdoError as e:
86 print("Received Mindopt exception.")
87 print(" - Code : {}".format(e.code))
88 print(" - Reason : {}".format(e.message))
89 except Exception as e:
90 print("Received exception.")
91 print(" - Explanation : {}".format(e))
92 finally:
93 # Step 4. Free the model.
94 model.free_mdl()