5.1.2. C 语言的建模和优化¶
在本节中,我们将使用 MindOpt C 语言的 API 来建模以及求解 线性规划问题示例 中的问题。
5.1.2.1. 按行输入:MdoLoEx1¶
首先,引入头文件:
23#include "Mindopt.h"
并创建优化模型:
52 /*------------------------------------------------------------------*/
53 /* Step 1. Create a model and change the parameters. */
54 /*------------------------------------------------------------------*/
55 /* Create an empty model. */
56 MDO_CHECK_CALL(Mdo_createMdl(&model));
接下来,我们通过 Mdo_setIntAttr()
将目标函数设置为 最小化 ,并调用 Mdo_addCol()
来添加四个优化变量,定义其下界、上界、名称和类型(关于 Mdo_setIntAttr()
和 Mdo_addCol()
的详细使用方式,请参考 C 接口函数):
58 /*------------------------------------------------------------------*/
59 /* Step 2. Input model. */
60 /*------------------------------------------------------------------*/
61 /* Change to minimization problem. */
62 MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
63
64 /* Add variables. */
65 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, 10.0, 1.0, 0, NULL, NULL, "x0", MDO_NO));
66 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x1", MDO_NO));
67 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x2", MDO_NO));
68 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x3", MDO_NO));
Note
矩阵的非零元将在后面按 列 输入;因此,Mdo_addCol()
中,按 列 输入非零元的相关参数 size
、 indices
、 value
分别用 0
、 NULL
、 NULL
代替(换句话说,此时问题无约束)。
以下我们将开始添加线性约束中的的非零元及其上下界,我们使用以下四列数组来定义线性约束;其中, row1_idx
和 row2_idx
分别表示第一和第二个约束中非零元素的位置(索引),而 row1_val
和 row2_val
则是与之相对应的非零数值。
47 const int row1_idx[] = { 0, 1, 2, 3 };
48 const double row1_val[] = { 1.0, 1.0, 2.0, 3.0 };
49 const int row2_idx[] = { 0, 2, 3 };
50 const double row2_val[] = { 1.0, -1.0, 6.0 };
我们调用 Mdo_addRow()
将输入约束:
70 /* Add constraints.
71 * Note that the nonzero elements are inputted in a row-wise order here.
72 */
73 MDO_CHECK_CALL(Mdo_addRow(model, 1.0, MDO_INFINITY, 4, row1_idx, row1_val, "c0"));
74 MDO_CHECK_CALL(Mdo_addRow(model, 1.0, 1.0, 3, row2_idx, row2_val, "c1"));
问题输入完成后,再调用 Mdo_solveProb()
求解优化问题,并通过 Mdo_displayResults()
查看优化结果:
76 /*------------------------------------------------------------------*/
77 /* Step 3. Solve the problem and populate the result. */
78 /*------------------------------------------------------------------*/
79 /* Solve the problem. */
80 MDO_CHECK_CALL(Mdo_solveProb(model));
81 Mdo_displayResults(model);
最后,调用 Mdo_freeMdl()
来释放内存:
84 /*------------------------------------------------------------------*/
85 /* Step 4. Free the model. */
86 /*------------------------------------------------------------------*/
87 /* Free the model. */
88 Mdo_freeMdl(&model);
MdoLoEx1.c 提供了完整源代码:
1/**
2 * Description
3 * -----------
4 *
5 * Linear optimization (row-wise input).
6 *
7 * Formulation
8 * -----------
9 *
10 * Minimize
11 * obj: 1 x0 + 1 x1 + 1 x2 + 1 x3
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 * End
21 */
22#include <stdio.h>
23#include "Mindopt.h"
24
25/* Macro to check the return code */
26#define MDO_CHECK_CALL(MDO_CALL) \
27 code = MDO_CALL; \
28 if (code != MDO_OKAY) \
29 { \
30 Mdo_explainResult(model, code, str); \
31 Mdo_freeMdl(&model); \
32 fprintf(stderr, "===================================\n"); \
33 fprintf(stderr, "Error : code <%d>\n", code); \
34 fprintf(stderr, "Reason : %s\n", str); \
35 fprintf(stderr, "===================================\n"); \
36 return (int)code; \
37 }
38
39int main(void)
40{
41 /* Variables. */
42 char str[1024] = { "\0" };
43 MdoMdl * model = NULL;
44 MdoResult code = MDO_OKAY;
45 MdoStatus status = MDO_UNKNOWN;
46
47 const int row1_idx[] = { 0, 1, 2, 3 };
48 const double row1_val[] = { 1.0, 1.0, 2.0, 3.0 };
49 const int row2_idx[] = { 0, 2, 3 };
50 const double row2_val[] = { 1.0, -1.0, 6.0 };
51
52 /*------------------------------------------------------------------*/
53 /* Step 1. Create a model and change the parameters. */
54 /*------------------------------------------------------------------*/
55 /* Create an empty model. */
56 MDO_CHECK_CALL(Mdo_createMdl(&model));
57
58 /*------------------------------------------------------------------*/
59 /* Step 2. Input model. */
60 /*------------------------------------------------------------------*/
61 /* Change to minimization problem. */
62 MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
63
64 /* Add variables. */
65 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, 10.0, 1.0, 0, NULL, NULL, "x0", MDO_NO));
66 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x1", MDO_NO));
67 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x2", MDO_NO));
68 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x3", MDO_NO));
69
70 /* Add constraints.
71 * Note that the nonzero elements are inputted in a row-wise order here.
72 */
73 MDO_CHECK_CALL(Mdo_addRow(model, 1.0, MDO_INFINITY, 4, row1_idx, row1_val, "c0"));
74 MDO_CHECK_CALL(Mdo_addRow(model, 1.0, 1.0, 3, row2_idx, row2_val, "c1"));
75
76 /*------------------------------------------------------------------*/
77 /* Step 3. Solve the problem and populate the result. */
78 /*------------------------------------------------------------------*/
79 /* Solve the problem. */
80 MDO_CHECK_CALL(Mdo_solveProb(model));
81 Mdo_displayResults(model);
82
83 /*------------------------------------------------------------------*/
84 /* Step 4. Free the model. */
85 /*------------------------------------------------------------------*/
86 /* Free the model. */
87 Mdo_freeMdl(&model);
88
89 return (int)code;
90}
5.1.2.2. 按列输入:MdoLoEx2¶
在下面的代码中,我们依然对上述问题进行建模,但改以 按列排列 的方式输入矩阵的非零元。换句话说,在增加一个新变量的同时,亦输入各约束在此列中相对应的非零元;一旦输入所有变量及非零元后,再修改线性约束的下界(left-hand-side;LHS)和上界(right-hand-side;RHS)。
此外,我们还调用 Mdo_getStatus()
来检查求解器的优化状态,并通过 Mdo_getRealAttr()
和 Mdo_getRealAttrArray()
来获取目标值和最优解( Mdo_getRealAttr()
和 Mdo_getRealAttrArray()
的详细使用方式,请参考 C 接口函数 )。
MdoLoEx2.c 提供了完整源代码:
1/**
2 * Description
3 * -----------
4 *
5 * Linear optimization (column-wise input).
6 *
7 * Formulation
8 * -----------
9 *
10 * Minimize
11 * obj: 1 x0 + 1 x1 + 1 x2 + 1 x3
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 * End
21 */
22#include <stdio.h>
23#include "Mindopt.h"
24
25/* Macro to check the return code */
26#define MDO_CHECK_CALL(MDO_CALL) \
27 code = MDO_CALL; \
28 if (code != MDO_OKAY) \
29 { \
30 Mdo_explainResult(model, code, str); \
31 Mdo_freeMdl(&model); \
32 fprintf(stderr, "===================================\n"); \
33 fprintf(stderr, "Error : code <%d>\n", code); \
34 fprintf(stderr, "Reason : %s\n", str); \
35 fprintf(stderr, "===================================\n"); \
36 return (int)code; \
37 }
38
39int main(void)
40{
41 /* Variables. */
42 char str[1024] = { "\0" };
43 MdoMdl * model = NULL;
44 MdoResult code = MDO_OKAY;
45 MdoStatus status = MDO_UNKNOWN;
46 double val, soln[4];
47 int j;
48 const int col1_idx[] = { 0, 1 };
49 const double col1_val[] = { 1.0, 1.0 };
50 const int col2_idx[] = { 0 };
51 const double col2_val[] = { 1.0 };
52 const int col3_idx[] = { 0, 1 };
53 const double col3_val[] = { 2.0, -1.0 };
54 const int col4_idx[] = { 0, 1 };
55 const double col4_val[] = { 3.0, 6.0 };
56
57 /*------------------------------------------------------------------*/
58 /* Step 1. Create a model and change the parameters. */
59 /*------------------------------------------------------------------*/
60 /* Create an empty model. */
61 MDO_CHECK_CALL(Mdo_createMdl(&model));
62
63 /*------------------------------------------------------------------*/
64 /* Step 2. Input model. */
65 /*------------------------------------------------------------------*/
66 /* Change to minimization problem. */
67 MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
68
69 /* Add variables.
70 * Note that the nonzero elements are inputted in a column-wise order here.
71 */
72 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, 10.0, 1.0, 2, col1_idx, col1_val, "x0", MDO_NO));
73 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 1, col2_idx, col2_val, "x1", MDO_NO));
74 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 2, col3_idx, col3_val, "x2", MDO_NO));
75 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 2, col4_idx, col4_val, "x3", MDO_NO));
76
77 /* Change the LHS value and RHS value of the constraints. */
78 MDO_CHECK_CALL(Mdo_setRealAttrIndex(model, MDO_REAL_ATTR_LHS, 0, 1.0));
79 MDO_CHECK_CALL(Mdo_setRealAttrIndex(model, MDO_REAL_ATTR_RHS, 0, MDO_INFINITY));
80 MDO_CHECK_CALL(Mdo_setRealAttrIndex(model, MDO_REAL_ATTR_LHS, 1, 1.0));
81 MDO_CHECK_CALL(Mdo_setRealAttrIndex(model, MDO_REAL_ATTR_RHS, 1, 1.0));
82
83 /*------------------------------------------------------------------*/
84 /* Step 3. Solve the problem and populate the result. */
85 /*------------------------------------------------------------------*/
86 /* Solve the problem. */
87 MDO_CHECK_CALL(Mdo_solveProb(model));
88 Mdo_displayResults(model);
89
90 switch (Mdo_getStatus(model))
91 {
92 case MDO_UNKNOWN:
93 printf("Optimizer terminated with an UNKNOWN status.\n");
94 break;
95 case MDO_OPTIMAL:
96 MDO_CHECK_CALL(Mdo_getRealAttr(model, MDO_REAL_ATTR_PRIMAL_OBJ_VAL, &val));
97 printf("Optimizer terminated with an OPTIMAL status.\n");
98 printf(" - Primal objective : %e.\n", val);
99 MDO_CHECK_CALL(Mdo_getRealAttrArray(model, MDO_REAL_ATTR_PRIMAL_SOLN, 0, 4, soln));
100 for (j = 0; j < 4; ++j)
101 {
102 printf("x[%d] = %e\n", j, soln[j]);
103 }
104 break;
105 case MDO_INFEASIBLE:
106 printf("Optimizer terminated with an INFEASIBLE status.\n");
107 break;
108 case MDO_UNBOUNDED:
109 printf("Optimizer terminated with an UNBOUNDED status.\n");
110 break;
111 case MDO_INF_OR_UBD:
112 printf("Optimizer terminated with an INFEASIBLE or UNBOUNDED status.\n");
113 break;
114 }
115
116 /*------------------------------------------------------------------*/
117 /* Step 4. Free the model. */
118 /*------------------------------------------------------------------*/
119 /* Free the model. */
120 Mdo_freeMdl(&model);
121
122 return (int)code;
123}
5.1.2.3. 进阶使用示例:MdoLoEx3¶
在下面的代码中,我们展示了其他进阶 API 的使用方式,如:输入模型、修改模型、获取基解、热启动的例子;关于 API 的完整使用方法,请参考 完整的API说明 。
1/**
2 * Description
3 * -----------
4 *
5 * Linear optimization.
6 * - Row input.
7 * - Column input.
8 * - Query.
9 */
10#include <stdio.h>
11#include <stdlib.h>
12#include "Mindopt.h"
13
14#define WRITE_LP
15#ifdef WIN32
16#define MY_FOLDER "C:/Users/your.name/research/MDO/xxx/"
17#else
18#define MY_FOLDER "/Users/Shared/Research/MDO/xxx/"
19#endif
20
21/* Macro to check the return code */
22#define MDO_CHECK_CALL(MDO_CALL) \
23 code = MDO_CALL; \
24 if (code != MDO_OKAY) \
25 { \
26 Mdo_explainResult(model, code, str); \
27 Mdo_freeMdl(&model); \
28 fprintf(stderr, "===================================\n"); \
29 fprintf(stderr, "Error : code <%d>\n", code); \
30 fprintf(stderr, "Reason : %s\n", str); \
31 fprintf(stderr, "===================================\n"); \
32 return (int)code; \
33 }
34
35int main(void)
36{
37 /* Variables. */
38 char str[1024] = { "\0" };
39 MdoMdl * model = NULL;
40 MdoResult code = MDO_OKAY;
41 MdoStatus status = MDO_UNKNOWN;
42 int i, j, c, r, e;
43
44 const int csr_bgn[] = {0, 4, 7};
45 const int csr_indices[] =
46 {
47 0, 1, 2, 3,
48 0, 2, 3
49 };
50 const double csr_values[] =
51 {
52 1.0, 1.0, 2.0, 3.0,
53 1.0, -1.0, 6.0
54 };
55
56 const int csc_bgn[] = {0, 2, 3, 5, 7};
57 const int csc_indices[] =
58 {
59 0, 1,
60 0,
61 0, 1,
62 0, 1
63 };
64 const double csc_values[] =
65 {
66 1.0, 1.0,
67 1.0,
68 2.0, -1.0,
69 3.0, 6.0
70 };
71
72 const double lhss[] = { 1, 1 };
73 const double rhss[] = { 1, MDO_INFINITY };
74 const char* row_names[] = { "cc0", NULL };
75
76 const double lbs[] = { 0.0, 0.0, 0.0, 0.0 };
77 const double ubs[] = { 10.0, MDO_INFINITY, MDO_INFINITY, MDO_INFINITY };
78 const double objs[] = { 1.0, 1.0, 1.0, 1.0 };
79 const char* col_names[] = { "xx0", "", "xx2", NULL };
80
81 /*------------------------------------------------------------------*/
82 /* Step 1. Create a model and change the parameters. */
83 /*------------------------------------------------------------------*/
84 printf(" Create a model and change the parameters.\n\n");
85 /* Create an empty model. */
86 MDO_CHECK_CALL(Mdo_createMdl(&model));
87
88 /*------------------------------------------------------------------*/
89 /* Step 2. Input model. */
90 /*------------------------------------------------------------------*/
91 printf("\nStep 2. Input model.\n\n");
92 /* The following three input methods will all result in the same model. */
93#if 0
94 /* Method 1. */
95 /* Change to minimization problem. */
96 MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
97
98 /* Add variables. */
99 for (i = 0; i < 4; ++i)
100 {
101 MDO_CHECK_CALL(Mdo_addCol(model, lbs[i], ubs[i], objs[i], 0, NULL, NULL, col_names[i], MDO_NO));
102 }
103 /* Add two constraints.
104 * The coefficients of the constraint matrix are inputted in a row-wise order.
105 */
106 MDO_CHECK_CALL(Mdo_addRows(model, 2, lhss, rhss, csr_bgn, csr_indices, csr_values, row_names));
107#endif
108#if 0
109 /* Method 2. */
110 /* Change to minimization problem. */
111 MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
112
113 /* Add variables and constraints.
114 * The coefficients of the constraint matrix are inputted in a column-wise order.
115 */
116 MDO_CHECK_CALL(Mdo_addCols(model, 4, lbs, ubs, objs, csc_bgn, csc_indices, csc_values, col_names, NULL));
117
118 /* Change LHS values and RHS values. */
119 MDO_CHECK_CALL(Mdo_setRealAttrArray(model, MDO_REAL_ATTR_LHS, 0, 2, lhss));
120 MDO_CHECK_CALL(Mdo_setRealAttrArray(model, MDO_REAL_ATTR_RHS, 0, 2, rhss));
121#endif
122#if 1
123 /* Method 3. */
124 /* Add four variables and two constraints in one shot.
125 * The coefficients of the constraint matrix are inputted in a column-wise order.
126 */
127 MDO_CHECK_CALL(Mdo_loadModel(model, 4, 2, csc_bgn, csc_indices, csc_values,
128 lbs, ubs, objs, NULL, 0.0, MDO_YES, lhss, rhss, col_names, row_names));
129#endif
130 MdoI32 idx[2] = { 0, 1 };
131 MdoReal tmp[2];
132 Mdo_getLhss(model, 2, idx, tmp);
133 for (int i = 0; i < 2; ++i)
134 {
135 printf("%d has LHS = %e\n", i, tmp[i]);
136 }
137 Mdo_getRhss(model, 2, idx, tmp);
138 for (int i = 0; i < 2; ++i)
139 {
140 printf("%d has RHS = %e\n", i, tmp[i]);
141 }
142
143 /*------------------------------------------------------------------*/
144 /* Step 3. Solve the problem and populate the result. */
145 /*------------------------------------------------------------------*/
146 printf("\nStep 3. Solve the problem and populate the result.\n\n");
147 Mdo_setIntParam(model, MDO_INT_PARAM_METHOD, 2);
148 Mdo_setIntParam(model, MDO_INT_PARAM_NUM_THREADS, 1);
149
150 /* Solve the problem. */
151 MDO_CHECK_CALL(Mdo_solveProb(model));
152 Mdo_displayResults(model);
153#ifdef WRITE_LP
154 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step3.lp"));
155#endif
156
157
158 Mdo_setIntParam(model, MDO_INT_PARAM_PRESOLVE, 0);
159 double newobj[4];
160 int indices[] = { 0, 1, 2, 3 };
161 MDO_CHECK_CALL(Mdo_getObjs(model, 4, indices, newobj));
162 for (int j = 0; j < 4; ++j)
163 {
164 newobj[j] = -newobj[j];
165 }
166#if 0
167 Mdo_setMaxObjSense(model);
168 MDO_CHECK_CALL(Mdo_setObjs(model, 4, indices, newobj));
169#else
170 MDO_CHECK_CALL(Mdo_loadModel(model, 4, 2, csc_bgn, csc_indices, csc_values,
171 lbs, ubs, newobj, NULL, 0.0, MDO_YES, lhss, rhss, col_names, row_names));
172#endif
173
174 MDO_CHECK_CALL(Mdo_solveProb(model));
175 Mdo_displayResults(model);
176#ifdef WRITE_LP
177 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step3-1.lp"));
178#endif
179
180
181 /*------------------------------------------------------------------*/
182 /* Step 4. Add another two variables and then resolve the problem. */
183 /*------------------------------------------------------------------*/
184 printf("\nStep 4. Add another two variables and then resolve the problem.\n\n");
185 /* Add another two variables. */
186 double lbs2[] = { 0, -2 };
187 double ubs2[] = { MDO_INFINITY, MDO_INFINITY };
188 double objs2[] = { 1, -1 };
189
190 int col_bgn[] = {0, 2, 4 };
191 int col_indices[] =
192 {
193 0, 1,
194 0, 1
195 };
196 double col_values[] =
197 {
198 1, 2,
199 3, 4
200 };
201 const char * col_names2[] = { "y1", "y2" };
202
203 MDO_CHECK_CALL(Mdo_addCols(model, 2, lbs2, ubs2, objs2, col_bgn, col_indices, col_values, NULL/*col_names2*/, NULL));
204
205 /* Solve the problem. */
206 MDO_CHECK_CALL(Mdo_solveProb(model));
207 Mdo_displayResults(model);
208#ifdef WRITE_LP
209 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step4.lp"));
210#endif
211
212 /*------------------------------------------------------------------*/
213 /* Step 5. Add another two constraints and then resolve the problem.*/
214 /*------------------------------------------------------------------*/
215 printf("\nStep 5. Add another two constraints and then resolve the problem.\n\n");
216 int bgn2[] = {0, 3, 6};
217 int indices2[] =
218 {
219 0, 1, 3,
220 0, 2, 3
221 };
222 double values2[] =
223 {
224 1.0, 1.0, -2.0,
225 1.0, -2.0, 6.0
226 };
227
228 const double lhss2[] = { 0, 1 };
229 const double rhss2[] = { 2, MDO_INFINITY };
230
231 const char* row_names2[] = { "cc2", "" };
232
233 /* Add two constraints. */
234 MDO_CHECK_CALL(Mdo_addRows(model, 2, lhss2, rhss2, bgn2, indices2, values2, row_names2));
235
236 /* Solve the problem. */
237 MDO_CHECK_CALL(Mdo_solveProb(model));
238 Mdo_displayResults(model);
239#ifdef WRITE_LP
240 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step5.lp"));
241#endif
242
243 /*------------------------------------------------------------------*/
244 /* Step 6. Obtain optimal basis. */
245 /*------------------------------------------------------------------*/
246 printf("\nStep 6. Obtain optimal basis.\n\n");
247 int * row_basis = (int *)calloc(4, sizeof(int));
248 int * col_basis = (int *)calloc(6, sizeof(int));
249 MDO_CHECK_CALL(Mdo_getIntAttrArray(model, MDO_INT_ATTR_ROW_BASIS, 0, 4, row_basis));
250 MDO_CHECK_CALL(Mdo_getIntAttrArray(model, MDO_INT_ATTR_COL_BASIS, 0, 6, col_basis));
251 /*
252 * isFree = 0,
253 * basic = 1,
254 * atUpperBound = 2,
255 * atLowerBound = 3,
256 * superBasic = 4,
257 * isFixed = 5,
258 */
259 for (i = 0; i < 4; ++i)
260 {
261 printf("Row [%d] status: %d\n", i, row_basis[i]);
262 }
263 for (j = 0; j < 6; ++j)
264 {
265 printf("Col [%d] status: %d\n", j, col_basis[j]);
266 }
267#ifdef WRITE_LP
268 MDO_CHECK_CALL(Mdo_writeSoln(model, MY_FOLDER "Step6.bas"));
269 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER "Step6.lp"));
270#endif
271
272 /*------------------------------------------------------------------*/
273 /* Step 7. Warm-start Simplex. */
274 /*------------------------------------------------------------------*/
275 printf("\nStep 7. Warm-start Simplex.\n\n");
276
277 /* Change the objective coefficients. */
278 int obj_indices[] = { 1, 2 };
279 double obj_values[] = { 3, -3 };
280 MDO_CHECK_CALL(Mdo_setObjs(model, 2, obj_indices, obj_values));
281
282 /* Load the basis. */
283 MDO_CHECK_CALL(Mdo_setIntAttrArray(model, MDO_INT_ATTR_ROW_BASIS, 0, 4, row_basis));
284 MDO_CHECK_CALL(Mdo_setIntAttrArray(model, MDO_INT_ATTR_COL_BASIS, 0, 6, col_basis));
285
286 /* Solve the problem. */
287 printf("Resolve with warm-start basis.\n");
288 Mdo_setIntParam(model, MDO_INT_PARAM_PRESOLVE, 0);
289 Mdo_setIntParam(model, MDO_INT_PARAM_METHOD, 0);
290 MDO_CHECK_CALL(Mdo_solveProb(model));
291 Mdo_displayResults(model);
292
293 free(row_basis);
294 free(col_basis);
295
296 /*------------------------------------------------------------------*/
297 /* Step 8. Model query. */
298 /*------------------------------------------------------------------*/
299 printf("\nStep 8. Model query.\n\n");
300 /* Query 1: Retrieve first two rows. */
301 printf("Query 1: Retrieve first two rows.\n");
302 int row_indices[2] = {0, 1};
303 int real_size;
304 /* Step 8.1. Get the total number of NNZs first. */
305 MDO_CHECK_CALL(Mdo_getRows(model, 2, row_indices, NULL, NULL, NULL, 0, &real_size));
306 int bgn3[2 + 1];
307 int * indices3 = (int *)calloc(real_size, sizeof(int));
308 double * values3 = (double *)calloc(real_size, sizeof(double));
309 printf("Number of nonzeros = %d.\n", real_size);
310
311 /* Step 8.2. Retrieve the rows. */
312 MDO_CHECK_CALL(Mdo_getRows(model, 2, row_indices, bgn3, indices3, values3, real_size, &real_size));
313 for (r = 0; r < 2; ++r)
314 {
315 for (e = bgn3[r]; e < bgn3[r + 1]; ++e)
316 {
317 printf("Element[%d, %d] = %e\n", row_indices[r], indices3[e], values3[e]);
318 }
319 }
320 free(indices3);
321 free(values3);
322
323 /* Query 2: Retrieve column 3 and column 5. */
324 printf("Query 2: Retrieve column 3 and column 5.\n");
325 int col_indices2[2] = {3, 5};
326 /* Step 8.3. Get the total number of NNZs first. */
327 MDO_CHECK_CALL(Mdo_getCols(model, 2, col_indices2, NULL, NULL, NULL, 0, &real_size));
328 int bgn4[2 + 1];
329 int * indices4 = (int *)calloc(real_size, sizeof(int));
330 double * values4 = (double *)calloc(real_size, sizeof(double));
331 printf("Number of nonzeros = %d.\n", real_size);
332
333 /* Step 8.4. Retrieve the columns. */
334 MDO_CHECK_CALL(Mdo_getCols(model, 2, col_indices2, bgn4, indices4, values4, real_size, &real_size));
335 for (c = 0; c < 2; ++c)
336 {
337 for (e = bgn4[c]; e < bgn4[c + 1]; ++e)
338 {
339 printf("Element[%d, %d] = %e\n", indices4[e], col_indices2[c], values4[e]);
340 }
341 }
342 free(indices4);
343 free(values4);
344
345 /*------------------------------------------------------------------*/
346 /* Step 9. Change row/col name and then delete rows and columns. */
347 /*------------------------------------------------------------------*/
348 char buf[256];
349 int itmp;
350 MDO_CHECK_CALL(Mdo_getRowName(model, 1, buf, 256, &itmp));
351 printf("Row 1 has name = %s\n", buf);
352 snprintf(buf, 256, "row_%d", 999);
353 itmp = 1;
354 char * pbuf[] = { buf };
355 MDO_CHECK_CALL(Mdo_setRowNames(model, 1, &itmp, pbuf));
356 MDO_CHECK_CALL(Mdo_getRowName(model, 1, buf, 256, &itmp));
357 printf("Updated Row 1 has name = %s (idx: %d)\n", buf, Mdo_getRowIndex(model, buf));
358 printf("Unknown index = %d\n", Mdo_getRowIndex(model, ""));
359
360 MDO_CHECK_CALL(Mdo_getColName(model, 1, buf, 256, &itmp));
361 printf("Col 1 has name = %s\n", buf);
362 snprintf(buf, 256, "col_%d", 999);
363 itmp = 1;
364 MDO_CHECK_CALL(Mdo_setColNames(model, 1, &itmp, pbuf));
365 MDO_CHECK_CALL(Mdo_getColName(model, 1, buf, 256, &itmp));
366 printf("Updated Col has name = %s (idx: %d)\n", buf, Mdo_getColIndex(model, buf));
367 printf("Unknown index = %d\n", Mdo_getColIndex(model, ""));
368
369
370#ifdef WRITE_LP
371 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step9.lp"));
372#endif
373
374 int delrow[2] = { 3, 1 };
375 MDO_CHECK_CALL(Mdo_deleteRows(model, 2, delrow));
376#ifdef WRITE_LP
377 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step9_delrow1.lp"));
378#endif
379 int delcol[2] = { 1, 3 };
380 MDO_CHECK_CALL(Mdo_deleteCols(model, 2, delcol));
381#ifdef WRITE_LP
382 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step9_delcol1.lp"));
383#endif
384
385 /*------------------------------------------------------------------*/
386 /* Step 10. Free the model. */
387 /*------------------------------------------------------------------*/
388 printf("\nStep 10. Free the model.n\n");
389 /* Free the model. */
390 Mdo_freeMdl(&model);
391
392 return (int)code;
393}