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说明 。
文件链接 MdoLoEx3.c 提供了完整源代码:
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#define MY_FOLDER "./"
16
17/* Macro to check the return code */
18#define MDO_CHECK_CALL(MDO_CALL) \
19 code = MDO_CALL; \
20 if (code != MDO_OKAY) \
21 { \
22 Mdo_explainResult(model, code, str); \
23 Mdo_freeMdl(&model); \
24 fprintf(stderr, "===================================\n"); \
25 fprintf(stderr, "Error : code <%d>\n", code); \
26 fprintf(stderr, "Reason : %s\n", str); \
27 fprintf(stderr, "===================================\n"); \
28 return (int)code; \
29 }
30
31int main(void)
32{
33 /* Variables. */
34 char str[1024] = { "\0" };
35 MdoMdl * model = NULL;
36 MdoResult code = MDO_OKAY;
37 MdoStatus status = MDO_UNKNOWN;
38 int i, j, c, r, e;
39
40 const int csr_bgn[] = {0, 4, 7};
41 const int csr_indices[] =
42 {
43 0, 1, 2, 3,
44 0, 2, 3
45 };
46 const double csr_values[] =
47 {
48 1.0, 1.0, 2.0, 3.0,
49 1.0, -1.0, 6.0
50 };
51
52 const int csc_bgn[] = {0, 2, 3, 5, 7};
53 const int csc_indices[] =
54 {
55 0, 1,
56 0,
57 0, 1,
58 0, 1
59 };
60 const double csc_values[] =
61 {
62 1.0, 1.0,
63 1.0,
64 2.0, -1.0,
65 3.0, 6.0
66 };
67
68 const double lhss[] = { 1, 1 };
69 const double rhss[] = { MDO_INFINITY, 1 };
70 const char* row_names[] = { "c0", "c1" };
71
72 const double lbs[] = { 0.0, 0.0, 0.0, 0.0 };
73 const double ubs[] = { 10.0, MDO_INFINITY, MDO_INFINITY, MDO_INFINITY };
74 const double objs[] = { 1.0, 1.0, 1.0, 1.0 };
75 const char* col_names[] = { "x0", "x1", "x2", "x3" };
76
77 /*------------------------------------------------------------------*/
78 /* Step 1. Create a model and change the parameters. */
79 /*------------------------------------------------------------------*/
80 printf(" Create a model and change the parameters.\n\n");
81 /* Create an empty model. */
82 MDO_CHECK_CALL(Mdo_createMdl(&model));
83
84 /*------------------------------------------------------------------*/
85 /* Step 2. Input model. */
86 /*------------------------------------------------------------------*/
87 printf("\nStep 2. Input model.\n\n");
88 /* The following three input methods will all result in the same model. */
89#if 0
90 /* Method 1. */
91 /* Change to minimization problem. */
92 MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
93
94 /* Add variables. */
95 for (i = 0; i < 4; ++i)
96 {
97 MDO_CHECK_CALL(Mdo_addCol(model, lbs[i], ubs[i], objs[i], 0, NULL, NULL, col_names[i], MDO_NO));
98 }
99 /* Add two constraints.
100 * The coefficients of the constraint matrix are inputted in a row-wise order.
101 */
102 MDO_CHECK_CALL(Mdo_addRows(model, 2, lhss, rhss, csr_bgn, csr_indices, csr_values, row_names));
103#endif
104#if 0
105 /* Method 2. */
106 /* Change to minimization problem. */
107 MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
108
109 /* Add variables and constraints.
110 * The coefficients of the constraint matrix are inputted in a column-wise order.
111 */
112 MDO_CHECK_CALL(Mdo_addCols(model, 4, lbs, ubs, objs, csc_bgn, csc_indices, csc_values, col_names, NULL));
113
114 /* Change LHS values and RHS values. */
115 MDO_CHECK_CALL(Mdo_setRealAttrArray(model, MDO_REAL_ATTR_LHS, 0, 2, lhss));
116 MDO_CHECK_CALL(Mdo_setRealAttrArray(model, MDO_REAL_ATTR_RHS, 0, 2, rhss));
117#endif
118#if 1
119 /* Method 3. */
120 /* Add four variables and two constraints in one shot.
121 * The coefficients of the constraint matrix are inputted in a column-wise order.
122 */
123 MDO_CHECK_CALL(Mdo_loadModel(model, 4, 2, csc_bgn, csc_indices, csc_values,
124 lbs, ubs, objs, NULL, 0.0, MDO_YES, lhss, rhss, col_names, row_names));
125#endif
126 MdoI32 idx[2] = { 0, 1 };
127 MdoReal tmp[2];
128 Mdo_getLhss(model, 2, idx, tmp);
129 for (int i = 0; i < 2; ++i)
130 {
131 printf("%d has LHS = %e\n", i, tmp[i]);
132 }
133 Mdo_getRhss(model, 2, idx, tmp);
134 for (int i = 0; i < 2; ++i)
135 {
136 printf("%d has RHS = %e\n", i, tmp[i]);
137 }
138
139 /*------------------------------------------------------------------*/
140 /* Step 3. Solve the problem and populate the result. */
141 /*------------------------------------------------------------------*/
142 printf("\nStep 3. Solve the problem and populate the result.\n\n");
143 Mdo_setIntParam(model, MDO_INT_PARAM_METHOD, 2);
144 Mdo_setIntParam(model, MDO_INT_PARAM_NUM_THREADS, 1);
145
146 /* Solve the problem. */
147 MDO_CHECK_CALL(Mdo_solveProb(model));
148 Mdo_displayResults(model);
149#ifdef WRITE_LP
150 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step3.lp"));
151#endif
152
153
154 Mdo_setIntParam(model, MDO_INT_PARAM_PRESOLVE, 0);
155 double newobj[4];
156 int indices[] = { 0, 1, 2, 3 };
157 MDO_CHECK_CALL(Mdo_getObjs(model, 4, indices, newobj));
158 for (int j = 0; j < 4; ++j)
159 {
160 newobj[j] = -newobj[j];
161 }
162#if 0
163 Mdo_setMaxObjSense(model);
164 MDO_CHECK_CALL(Mdo_setObjs(model, 4, indices, newobj));
165#else
166 MDO_CHECK_CALL(Mdo_loadModel(model, 4, 2, csc_bgn, csc_indices, csc_values,
167 lbs, ubs, newobj, NULL, 0.0, MDO_YES, lhss, rhss, col_names, row_names));
168#endif
169
170 MDO_CHECK_CALL(Mdo_solveProb(model));
171 Mdo_displayResults(model);
172#ifdef WRITE_LP
173 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step3-1.lp"));
174#endif
175
176
177 /*------------------------------------------------------------------*/
178 /* Step 4. Add another two variables and then resolve the problem. */
179 /*------------------------------------------------------------------*/
180 printf("\nStep 4. Add another two variables and then resolve the problem.\n\n");
181 /* Add another two variables. */
182 double lbs2[] = { 0, -2 };
183 double ubs2[] = { MDO_INFINITY, MDO_INFINITY };
184 double objs2[] = { 1, -1 };
185
186 int col_bgn[] = {0, 2, 4 };
187 int col_indices[] =
188 {
189 0, 1,
190 0, 1
191 };
192 double col_values[] =
193 {
194 1, 2,
195 3, 4
196 };
197 const char * col_names2[] = { "y1", "y2" };
198
199 MDO_CHECK_CALL(Mdo_addCols(model, 2, lbs2, ubs2, objs2, col_bgn, col_indices, col_values, col_names2, NULL));
200
201 /* Solve the problem. */
202 MDO_CHECK_CALL(Mdo_solveProb(model));
203 Mdo_displayResults(model);
204#ifdef WRITE_LP
205 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step4.lp"));
206#endif
207
208 /*------------------------------------------------------------------*/
209 /* Step 5. Add another two constraints and then resolve the problem.*/
210 /*------------------------------------------------------------------*/
211 printf("\nStep 5. Add another two constraints and then resolve the problem.\n\n");
212 int bgn2[] = {0, 3, 6};
213 int indices2[] =
214 {
215 0, 1, 3,
216 0, 2, 3
217 };
218 double values2[] =
219 {
220 1.0, 1.0, -2.0,
221 1.0, -2.0, 6.0
222 };
223
224 const double lhss2[] = { 0, 1 };
225 const double rhss2[] = { 2, MDO_INFINITY };
226
227 const char* row_names2[] = { "C2", "C3" };
228
229 /* Add two constraints. */
230 MDO_CHECK_CALL(Mdo_addRows(model, 2, lhss2, rhss2, bgn2, indices2, values2, row_names2));
231
232 /* Solve the problem. */
233 MDO_CHECK_CALL(Mdo_solveProb(model));
234 Mdo_displayResults(model);
235#ifdef WRITE_LP
236 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step5.lp"));
237#endif
238
239 /*------------------------------------------------------------------*/
240 /* Step 6. Obtain optimal basis. */
241 /*------------------------------------------------------------------*/
242 printf("\nStep 6. Obtain optimal basis.\n\n");
243 int * row_basis = (int *)calloc(4, sizeof(int));
244 int * col_basis = (int *)calloc(6, sizeof(int));
245 MDO_CHECK_CALL(Mdo_getIntAttrArray(model, MDO_INT_ATTR_ROW_BASIS, 0, 4, row_basis));
246 MDO_CHECK_CALL(Mdo_getIntAttrArray(model, MDO_INT_ATTR_COL_BASIS, 0, 6, col_basis));
247 /*
248 * isFree = 0,
249 * basic = 1,
250 * atUpperBound = 2,
251 * atLowerBound = 3,
252 * superBasic = 4,
253 * isFixed = 5,
254 */
255 for (i = 0; i < 4; ++i)
256 {
257 printf("Row [%d] status: %d\n", i, row_basis[i]);
258 }
259 for (j = 0; j < 6; ++j)
260 {
261 printf("Col [%d] status: %d\n", j, col_basis[j]);
262 }
263#ifdef WRITE_LP
264 MDO_CHECK_CALL(Mdo_writeSoln(model, MY_FOLDER "Step6.bas"));
265 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER "Step6.lp"));
266#endif
267
268 /*------------------------------------------------------------------*/
269 /* Step 7. Warm-start Simplex. */
270 /*------------------------------------------------------------------*/
271 printf("\nStep 7. Warm-start Simplex.\n\n");
272
273 /* Change the objective coefficients. */
274 int obj_indices[] = { 1, 2 };
275 double obj_values[] = { 3, -3 };
276 MDO_CHECK_CALL(Mdo_setObjs(model, 2, obj_indices, obj_values));
277
278 /* Load the basis. */
279 MDO_CHECK_CALL(Mdo_setIntAttrArray(model, MDO_INT_ATTR_ROW_BASIS, 0, 4, row_basis));
280 MDO_CHECK_CALL(Mdo_setIntAttrArray(model, MDO_INT_ATTR_COL_BASIS, 0, 6, col_basis));
281
282 /* Solve the problem. */
283 printf("Resolve with warm-start basis.\n");
284 Mdo_setIntParam(model, MDO_INT_PARAM_PRESOLVE, 0);
285 Mdo_setIntParam(model, MDO_INT_PARAM_METHOD, 0);
286 MDO_CHECK_CALL(Mdo_solveProb(model));
287 Mdo_displayResults(model);
288
289 free(row_basis);
290 free(col_basis);
291
292 /*------------------------------------------------------------------*/
293 /* Step 8. Model query. */
294 /*------------------------------------------------------------------*/
295 printf("\nStep 8. Model query.\n\n");
296 /* Query 1: Retrieve first two rows. */
297 printf("Query 1: Retrieve first two rows.\n");
298 int row_indices[2] = {0, 1};
299 int real_size;
300 /* Step 8.1. Get the total number of NNZs first. */
301 MDO_CHECK_CALL(Mdo_getRows(model, 2, row_indices, NULL, NULL, NULL, 0, &real_size));
302 int bgn3[2 + 1];
303 int * indices3 = (int *)calloc(real_size, sizeof(int));
304 double * values3 = (double *)calloc(real_size, sizeof(double));
305 printf("Number of nonzeros = %d.\n", real_size);
306
307 /* Step 8.2. Retrieve the rows. */
308 MDO_CHECK_CALL(Mdo_getRows(model, 2, row_indices, bgn3, indices3, values3, real_size, &real_size));
309 for (r = 0; r < 2; ++r)
310 {
311 for (e = bgn3[r]; e < bgn3[r + 1]; ++e)
312 {
313 printf("Element[%d, %d] = %e\n", row_indices[r], indices3[e], values3[e]);
314 }
315 }
316 free(indices3);
317 free(values3);
318
319 /* Query 2: Retrieve column 3 and column 5. */
320 printf("Query 2: Retrieve column 3 and column 5.\n");
321 int col_indices2[2] = {3, 5};
322 /* Step 8.3. Get the total number of NNZs first. */
323 MDO_CHECK_CALL(Mdo_getCols(model, 2, col_indices2, NULL, NULL, NULL, 0, &real_size));
324 int bgn4[2 + 1];
325 int * indices4 = (int *)calloc(real_size, sizeof(int));
326 double * values4 = (double *)calloc(real_size, sizeof(double));
327 printf("Number of nonzeros = %d.\n", real_size);
328
329 /* Step 8.4. Retrieve the columns. */
330 MDO_CHECK_CALL(Mdo_getCols(model, 2, col_indices2, bgn4, indices4, values4, real_size, &real_size));
331 for (c = 0; c < 2; ++c)
332 {
333 for (e = bgn4[c]; e < bgn4[c + 1]; ++e)
334 {
335 printf("Element[%d, %d] = %e\n", indices4[e], col_indices2[c], values4[e]);
336 }
337 }
338 free(indices4);
339 free(values4);
340
341 /*------------------------------------------------------------------*/
342 /* Step 9. Change row/col name and then delete rows and columns. */
343 /*------------------------------------------------------------------*/
344 char buf[256];
345 int itmp;
346 MDO_CHECK_CALL(Mdo_getRowName(model, 1, buf, 256, &itmp));
347 printf("Row 1 has name = %s\n", buf);
348 snprintf(buf, 256, "row_%d", 999);
349 itmp = 1;
350 char * pbuf[] = { buf };
351 MDO_CHECK_CALL(Mdo_setRowNames(model, 1, &itmp, pbuf));
352 MDO_CHECK_CALL(Mdo_getRowName(model, 1, buf, 256, &itmp));
353 printf("Updated Row 1 has name = %s (idx: %d)\n", buf, Mdo_getRowIndex(model, buf));
354 printf("Unknown index = %d\n", Mdo_getRowIndex(model, ""));
355
356 MDO_CHECK_CALL(Mdo_getColName(model, 1, buf, 256, &itmp));
357 printf("Col 1 has name = %s\n", buf);
358 snprintf(buf, 256, "col_%d", 999);
359 itmp = 1;
360 MDO_CHECK_CALL(Mdo_setColNames(model, 1, &itmp, pbuf));
361 MDO_CHECK_CALL(Mdo_getColName(model, 1, buf, 256, &itmp));
362 printf("Updated Col has name = %s (idx: %d)\n", buf, Mdo_getColIndex(model, buf));
363 printf("Unknown index = %d\n", Mdo_getColIndex(model, ""));
364
365
366#ifdef WRITE_LP
367 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step9.lp"));
368#endif
369
370 int delrow[2] = { 3, 1 };
371 MDO_CHECK_CALL(Mdo_deleteRows(model, 2, delrow));
372#ifdef WRITE_LP
373 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step9_delrow1.lp"));
374#endif
375 int delcol[2] = { 1, 3 };
376 MDO_CHECK_CALL(Mdo_deleteCols(model, 2, delcol));
377#ifdef WRITE_LP
378 MDO_CHECK_CALL(Mdo_writeProb(model, MY_FOLDER"Step9_delcol1.lp"));
379#endif
380
381 /*------------------------------------------------------------------*/
382 /* Step 10. Free the model. */
383 /*------------------------------------------------------------------*/
384 printf("\nStep 10. Free the model.n\n");
385 /* Free the model. */
386 Mdo_freeMdl(&model);
387
388 return (int)code;
389}