1 | /* glplpx01.c (obsolete API routines) */ |
---|
2 | |
---|
3 | /*********************************************************************** |
---|
4 | * This code is part of GLPK (GNU Linear Programming Kit). |
---|
5 | * |
---|
6 | * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, |
---|
7 | * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, |
---|
8 | * Moscow Aviation Institute, Moscow, Russia. All rights reserved. |
---|
9 | * E-mail: <mao@gnu.org>. |
---|
10 | * |
---|
11 | * GLPK is free software: you can redistribute it and/or modify it |
---|
12 | * under the terms of the GNU General Public License as published by |
---|
13 | * the Free Software Foundation, either version 3 of the License, or |
---|
14 | * (at your option) any later version. |
---|
15 | * |
---|
16 | * GLPK is distributed in the hope that it will be useful, but WITHOUT |
---|
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
---|
18 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
---|
19 | * License for more details. |
---|
20 | * |
---|
21 | * You should have received a copy of the GNU General Public License |
---|
22 | * along with GLPK. If not, see <http://www.gnu.org/licenses/>. |
---|
23 | ***********************************************************************/ |
---|
24 | |
---|
25 | #include "glpapi.h" |
---|
26 | |
---|
27 | struct LPXCPS |
---|
28 | { /* control parameters and statistics */ |
---|
29 | int msg_lev; |
---|
30 | /* level of messages output by the solver: |
---|
31 | 0 - no output |
---|
32 | 1 - error messages only |
---|
33 | 2 - normal output |
---|
34 | 3 - full output (includes informational messages) */ |
---|
35 | int scale; |
---|
36 | /* scaling option: |
---|
37 | 0 - no scaling |
---|
38 | 1 - equilibration scaling |
---|
39 | 2 - geometric mean scaling |
---|
40 | 3 - geometric mean scaling, then equilibration scaling */ |
---|
41 | int dual; |
---|
42 | /* dual simplex option: |
---|
43 | 0 - use primal simplex |
---|
44 | 1 - use dual simplex */ |
---|
45 | int price; |
---|
46 | /* pricing option (for both primal and dual simplex): |
---|
47 | 0 - textbook pricing |
---|
48 | 1 - steepest edge pricing */ |
---|
49 | double relax; |
---|
50 | /* relaxation parameter used in the ratio test; if it is zero, |
---|
51 | the textbook ratio test is used; if it is non-zero (should be |
---|
52 | positive), Harris' two-pass ratio test is used; in the latter |
---|
53 | case on the first pass basic variables (in the case of primal |
---|
54 | simplex) or reduced costs of non-basic variables (in the case |
---|
55 | of dual simplex) are allowed to slightly violate their bounds, |
---|
56 | but not more than (relax * tol_bnd) or (relax * tol_dj) (thus, |
---|
57 | relax is a percentage of tol_bnd or tol_dj) */ |
---|
58 | double tol_bnd; |
---|
59 | /* relative tolerance used to check if the current basic solution |
---|
60 | is primal feasible */ |
---|
61 | double tol_dj; |
---|
62 | /* absolute tolerance used to check if the current basic solution |
---|
63 | is dual feasible */ |
---|
64 | double tol_piv; |
---|
65 | /* relative tolerance used to choose eligible pivotal elements of |
---|
66 | the simplex table in the ratio test */ |
---|
67 | int round; |
---|
68 | /* solution rounding option: |
---|
69 | 0 - report all computed values and reduced costs "as is" |
---|
70 | 1 - if possible (allowed by the tolerances), replace computed |
---|
71 | values and reduced costs which are close to zero by exact |
---|
72 | zeros */ |
---|
73 | double obj_ll; |
---|
74 | /* lower limit of the objective function; if on the phase II the |
---|
75 | objective function reaches this limit and continues decreasing, |
---|
76 | the solver stops the search */ |
---|
77 | double obj_ul; |
---|
78 | /* upper limit of the objective function; if on the phase II the |
---|
79 | objective function reaches this limit and continues increasing, |
---|
80 | the solver stops the search */ |
---|
81 | int it_lim; |
---|
82 | /* simplex iterations limit; if this value is positive, it is |
---|
83 | decreased by one each time when one simplex iteration has been |
---|
84 | performed, and reaching zero value signals the solver to stop |
---|
85 | the search; negative value means no iterations limit */ |
---|
86 | double tm_lim; |
---|
87 | /* searching time limit, in seconds; if this value is positive, |
---|
88 | it is decreased each time when one simplex iteration has been |
---|
89 | performed by the amount of time spent for the iteration, and |
---|
90 | reaching zero value signals the solver to stop the search; |
---|
91 | negative value means no time limit */ |
---|
92 | int out_frq; |
---|
93 | /* output frequency, in iterations; this parameter specifies how |
---|
94 | frequently the solver sends information about the solution to |
---|
95 | the standard output */ |
---|
96 | double out_dly; |
---|
97 | /* output delay, in seconds; this parameter specifies how long |
---|
98 | the solver should delay sending information about the solution |
---|
99 | to the standard output; zero value means no delay */ |
---|
100 | int branch; /* MIP */ |
---|
101 | /* branching heuristic: |
---|
102 | 0 - branch on first variable |
---|
103 | 1 - branch on last variable |
---|
104 | 2 - branch using heuristic by Driebeck and Tomlin |
---|
105 | 3 - branch on most fractional variable */ |
---|
106 | int btrack; /* MIP */ |
---|
107 | /* backtracking heuristic: |
---|
108 | 0 - select most recent node (depth first search) |
---|
109 | 1 - select earliest node (breadth first search) |
---|
110 | 2 - select node using the best projection heuristic |
---|
111 | 3 - select node with best local bound */ |
---|
112 | double tol_int; /* MIP */ |
---|
113 | /* absolute tolerance used to check if the current basic solution |
---|
114 | is integer feasible */ |
---|
115 | double tol_obj; /* MIP */ |
---|
116 | /* relative tolerance used to check if the value of the objective |
---|
117 | function is not better than in the best known integer feasible |
---|
118 | solution */ |
---|
119 | int mps_info; /* lpx_write_mps */ |
---|
120 | /* if this flag is set, the routine lpx_write_mps outputs several |
---|
121 | comment cards that contains some information about the problem; |
---|
122 | otherwise the routine outputs no comment cards */ |
---|
123 | int mps_obj; /* lpx_write_mps */ |
---|
124 | /* this parameter tells the routine lpx_write_mps how to output |
---|
125 | the objective function row: |
---|
126 | 0 - never output objective function row |
---|
127 | 1 - always output objective function row |
---|
128 | 2 - output objective function row if and only if the problem |
---|
129 | has no free rows */ |
---|
130 | int mps_orig; /* lpx_write_mps */ |
---|
131 | /* if this flag is set, the routine lpx_write_mps uses original |
---|
132 | row and column symbolic names; otherwise the routine generates |
---|
133 | plain names using ordinal numbers of rows and columns */ |
---|
134 | int mps_wide; /* lpx_write_mps */ |
---|
135 | /* if this flag is set, the routine lpx_write_mps uses all data |
---|
136 | fields; otherwise the routine keeps fields 5 and 6 empty */ |
---|
137 | int mps_free; /* lpx_write_mps */ |
---|
138 | /* if this flag is set, the routine lpx_write_mps omits column |
---|
139 | and vector names everytime if possible (free style); otherwise |
---|
140 | the routine never omits these names (pedantic style) */ |
---|
141 | int mps_skip; /* lpx_write_mps */ |
---|
142 | /* if this flag is set, the routine lpx_write_mps skips empty |
---|
143 | columns (i.e. which has no constraint coefficients); otherwise |
---|
144 | the routine outputs all columns */ |
---|
145 | int lpt_orig; /* lpx_write_lpt */ |
---|
146 | /* if this flag is set, the routine lpx_write_lpt uses original |
---|
147 | row and column symbolic names; otherwise the routine generates |
---|
148 | plain names using ordinal numbers of rows and columns */ |
---|
149 | int presol; /* lpx_simplex */ |
---|
150 | /* LP presolver option: |
---|
151 | 0 - do not use LP presolver |
---|
152 | 1 - use LP presolver */ |
---|
153 | int binarize; /* lpx_intopt */ |
---|
154 | /* if this flag is set, the routine lpx_intopt replaces integer |
---|
155 | columns by binary ones */ |
---|
156 | int use_cuts; /* lpx_intopt */ |
---|
157 | /* if this flag is set, the routine lpx_intopt tries generating |
---|
158 | cutting planes: |
---|
159 | LPX_C_COVER - mixed cover cuts |
---|
160 | LPX_C_CLIQUE - clique cuts |
---|
161 | LPX_C_GOMORY - Gomory's mixed integer cuts |
---|
162 | LPX_C_ALL - all cuts */ |
---|
163 | double mip_gap; /* MIP */ |
---|
164 | /* relative MIP gap tolerance */ |
---|
165 | }; |
---|
166 | |
---|
167 | LPX *lpx_create_prob(void) |
---|
168 | { /* create problem object */ |
---|
169 | return glp_create_prob(); |
---|
170 | } |
---|
171 | |
---|
172 | void lpx_set_prob_name(LPX *lp, const char *name) |
---|
173 | { /* assign (change) problem name */ |
---|
174 | glp_set_prob_name(lp, name); |
---|
175 | return; |
---|
176 | } |
---|
177 | |
---|
178 | void lpx_set_obj_name(LPX *lp, const char *name) |
---|
179 | { /* assign (change) objective function name */ |
---|
180 | glp_set_obj_name(lp, name); |
---|
181 | return; |
---|
182 | } |
---|
183 | |
---|
184 | void lpx_set_obj_dir(LPX *lp, int dir) |
---|
185 | { /* set (change) optimization direction flag */ |
---|
186 | glp_set_obj_dir(lp, dir - LPX_MIN + GLP_MIN); |
---|
187 | return; |
---|
188 | } |
---|
189 | |
---|
190 | int lpx_add_rows(LPX *lp, int nrs) |
---|
191 | { /* add new rows to problem object */ |
---|
192 | return glp_add_rows(lp, nrs); |
---|
193 | } |
---|
194 | |
---|
195 | int lpx_add_cols(LPX *lp, int ncs) |
---|
196 | { /* add new columns to problem object */ |
---|
197 | return glp_add_cols(lp, ncs); |
---|
198 | } |
---|
199 | |
---|
200 | void lpx_set_row_name(LPX *lp, int i, const char *name) |
---|
201 | { /* assign (change) row name */ |
---|
202 | glp_set_row_name(lp, i, name); |
---|
203 | return; |
---|
204 | } |
---|
205 | |
---|
206 | void lpx_set_col_name(LPX *lp, int j, const char *name) |
---|
207 | { /* assign (change) column name */ |
---|
208 | glp_set_col_name(lp, j, name); |
---|
209 | return; |
---|
210 | } |
---|
211 | |
---|
212 | void lpx_set_row_bnds(LPX *lp, int i, int type, double lb, double ub) |
---|
213 | { /* set (change) row bounds */ |
---|
214 | glp_set_row_bnds(lp, i, type - LPX_FR + GLP_FR, lb, ub); |
---|
215 | return; |
---|
216 | } |
---|
217 | |
---|
218 | void lpx_set_col_bnds(LPX *lp, int j, int type, double lb, double ub) |
---|
219 | { /* set (change) column bounds */ |
---|
220 | glp_set_col_bnds(lp, j, type - LPX_FR + GLP_FR, lb, ub); |
---|
221 | return; |
---|
222 | } |
---|
223 | |
---|
224 | void lpx_set_obj_coef(glp_prob *lp, int j, double coef) |
---|
225 | { /* set (change) obj. coefficient or constant term */ |
---|
226 | glp_set_obj_coef(lp, j, coef); |
---|
227 | return; |
---|
228 | } |
---|
229 | |
---|
230 | void lpx_set_mat_row(LPX *lp, int i, int len, const int ind[], |
---|
231 | const double val[]) |
---|
232 | { /* set (replace) row of the constraint matrix */ |
---|
233 | glp_set_mat_row(lp, i, len, ind, val); |
---|
234 | return; |
---|
235 | } |
---|
236 | |
---|
237 | void lpx_set_mat_col(LPX *lp, int j, int len, const int ind[], |
---|
238 | const double val[]) |
---|
239 | { /* set (replace) column of the constraint matrix */ |
---|
240 | glp_set_mat_col(lp, j, len, ind, val); |
---|
241 | return; |
---|
242 | } |
---|
243 | |
---|
244 | void lpx_load_matrix(LPX *lp, int ne, const int ia[], const int ja[], |
---|
245 | const double ar[]) |
---|
246 | { /* load (replace) the whole constraint matrix */ |
---|
247 | glp_load_matrix(lp, ne, ia, ja, ar); |
---|
248 | return; |
---|
249 | } |
---|
250 | |
---|
251 | void lpx_del_rows(LPX *lp, int nrs, const int num[]) |
---|
252 | { /* delete specified rows from problem object */ |
---|
253 | glp_del_rows(lp, nrs, num); |
---|
254 | return; |
---|
255 | } |
---|
256 | |
---|
257 | void lpx_del_cols(LPX *lp, int ncs, const int num[]) |
---|
258 | { /* delete specified columns from problem object */ |
---|
259 | glp_del_cols(lp, ncs, num); |
---|
260 | return; |
---|
261 | } |
---|
262 | |
---|
263 | void lpx_delete_prob(LPX *lp) |
---|
264 | { /* delete problem object */ |
---|
265 | glp_delete_prob(lp); |
---|
266 | return; |
---|
267 | } |
---|
268 | |
---|
269 | const char *lpx_get_prob_name(LPX *lp) |
---|
270 | { /* retrieve problem name */ |
---|
271 | return glp_get_prob_name(lp); |
---|
272 | } |
---|
273 | |
---|
274 | const char *lpx_get_obj_name(LPX *lp) |
---|
275 | { /* retrieve objective function name */ |
---|
276 | return glp_get_obj_name(lp); |
---|
277 | } |
---|
278 | |
---|
279 | int lpx_get_obj_dir(LPX *lp) |
---|
280 | { /* retrieve optimization direction flag */ |
---|
281 | return glp_get_obj_dir(lp) - GLP_MIN + LPX_MIN; |
---|
282 | } |
---|
283 | |
---|
284 | int lpx_get_num_rows(LPX *lp) |
---|
285 | { /* retrieve number of rows */ |
---|
286 | return glp_get_num_rows(lp); |
---|
287 | } |
---|
288 | |
---|
289 | int lpx_get_num_cols(LPX *lp) |
---|
290 | { /* retrieve number of columns */ |
---|
291 | return glp_get_num_cols(lp); |
---|
292 | } |
---|
293 | |
---|
294 | const char *lpx_get_row_name(LPX *lp, int i) |
---|
295 | { /* retrieve row name */ |
---|
296 | return glp_get_row_name(lp, i); |
---|
297 | } |
---|
298 | |
---|
299 | const char *lpx_get_col_name(LPX *lp, int j) |
---|
300 | { /* retrieve column name */ |
---|
301 | return glp_get_col_name(lp, j); |
---|
302 | } |
---|
303 | |
---|
304 | int lpx_get_row_type(LPX *lp, int i) |
---|
305 | { /* retrieve row type */ |
---|
306 | return glp_get_row_type(lp, i) - GLP_FR + LPX_FR; |
---|
307 | } |
---|
308 | |
---|
309 | double lpx_get_row_lb(glp_prob *lp, int i) |
---|
310 | { /* retrieve row lower bound */ |
---|
311 | double lb; |
---|
312 | lb = glp_get_row_lb(lp, i); |
---|
313 | if (lb == -DBL_MAX) lb = 0.0; |
---|
314 | return lb; |
---|
315 | } |
---|
316 | |
---|
317 | double lpx_get_row_ub(glp_prob *lp, int i) |
---|
318 | { /* retrieve row upper bound */ |
---|
319 | double ub; |
---|
320 | ub = glp_get_row_ub(lp, i); |
---|
321 | if (ub == +DBL_MAX) ub = 0.0; |
---|
322 | return ub; |
---|
323 | } |
---|
324 | |
---|
325 | void lpx_get_row_bnds(glp_prob *lp, int i, int *typx, double *lb, |
---|
326 | double *ub) |
---|
327 | { /* retrieve row bounds */ |
---|
328 | if (typx != NULL) *typx = lpx_get_row_type(lp, i); |
---|
329 | if (lb != NULL) *lb = lpx_get_row_lb(lp, i); |
---|
330 | if (ub != NULL) *ub = lpx_get_row_ub(lp, i); |
---|
331 | return; |
---|
332 | } |
---|
333 | |
---|
334 | int lpx_get_col_type(LPX *lp, int j) |
---|
335 | { /* retrieve column type */ |
---|
336 | return glp_get_col_type(lp, j) - GLP_FR + LPX_FR; |
---|
337 | } |
---|
338 | |
---|
339 | double lpx_get_col_lb(glp_prob *lp, int j) |
---|
340 | { /* retrieve column lower bound */ |
---|
341 | double lb; |
---|
342 | lb = glp_get_col_lb(lp, j); |
---|
343 | if (lb == -DBL_MAX) lb = 0.0; |
---|
344 | return lb; |
---|
345 | } |
---|
346 | |
---|
347 | double lpx_get_col_ub(glp_prob *lp, int j) |
---|
348 | { /* retrieve column upper bound */ |
---|
349 | double ub; |
---|
350 | ub = glp_get_col_ub(lp, j); |
---|
351 | if (ub == +DBL_MAX) ub = 0.0; |
---|
352 | return ub; |
---|
353 | } |
---|
354 | |
---|
355 | void lpx_get_col_bnds(glp_prob *lp, int j, int *typx, double *lb, |
---|
356 | double *ub) |
---|
357 | { /* retrieve column bounds */ |
---|
358 | if (typx != NULL) *typx = lpx_get_col_type(lp, j); |
---|
359 | if (lb != NULL) *lb = lpx_get_col_lb(lp, j); |
---|
360 | if (ub != NULL) *ub = lpx_get_col_ub(lp, j); |
---|
361 | return; |
---|
362 | } |
---|
363 | |
---|
364 | double lpx_get_obj_coef(LPX *lp, int j) |
---|
365 | { /* retrieve obj. coefficient or constant term */ |
---|
366 | return glp_get_obj_coef(lp, j); |
---|
367 | } |
---|
368 | |
---|
369 | int lpx_get_num_nz(LPX *lp) |
---|
370 | { /* retrieve number of constraint coefficients */ |
---|
371 | return glp_get_num_nz(lp); |
---|
372 | } |
---|
373 | |
---|
374 | int lpx_get_mat_row(LPX *lp, int i, int ind[], double val[]) |
---|
375 | { /* retrieve row of the constraint matrix */ |
---|
376 | return glp_get_mat_row(lp, i, ind, val); |
---|
377 | } |
---|
378 | |
---|
379 | int lpx_get_mat_col(LPX *lp, int j, int ind[], double val[]) |
---|
380 | { /* retrieve column of the constraint matrix */ |
---|
381 | return glp_get_mat_col(lp, j, ind, val); |
---|
382 | } |
---|
383 | |
---|
384 | void lpx_create_index(LPX *lp) |
---|
385 | { /* create the name index */ |
---|
386 | glp_create_index(lp); |
---|
387 | return; |
---|
388 | } |
---|
389 | |
---|
390 | int lpx_find_row(LPX *lp, const char *name) |
---|
391 | { /* find row by its name */ |
---|
392 | return glp_find_row(lp, name); |
---|
393 | } |
---|
394 | |
---|
395 | int lpx_find_col(LPX *lp, const char *name) |
---|
396 | { /* find column by its name */ |
---|
397 | return glp_find_col(lp, name); |
---|
398 | } |
---|
399 | |
---|
400 | void lpx_delete_index(LPX *lp) |
---|
401 | { /* delete the name index */ |
---|
402 | glp_delete_index(lp); |
---|
403 | return; |
---|
404 | } |
---|
405 | |
---|
406 | void lpx_scale_prob(LPX *lp) |
---|
407 | { /* scale problem data */ |
---|
408 | switch (lpx_get_int_parm(lp, LPX_K_SCALE)) |
---|
409 | { case 0: |
---|
410 | /* no scaling */ |
---|
411 | glp_unscale_prob(lp); |
---|
412 | break; |
---|
413 | case 1: |
---|
414 | /* equilibration scaling */ |
---|
415 | glp_scale_prob(lp, GLP_SF_EQ); |
---|
416 | break; |
---|
417 | case 2: |
---|
418 | /* geometric mean scaling */ |
---|
419 | glp_scale_prob(lp, GLP_SF_GM); |
---|
420 | break; |
---|
421 | case 3: |
---|
422 | /* geometric mean scaling, then equilibration scaling */ |
---|
423 | glp_scale_prob(lp, GLP_SF_GM | GLP_SF_EQ); |
---|
424 | break; |
---|
425 | default: |
---|
426 | xassert(lp != lp); |
---|
427 | } |
---|
428 | return; |
---|
429 | } |
---|
430 | |
---|
431 | void lpx_unscale_prob(LPX *lp) |
---|
432 | { /* unscale problem data */ |
---|
433 | glp_unscale_prob(lp); |
---|
434 | return; |
---|
435 | } |
---|
436 | |
---|
437 | void lpx_set_row_stat(LPX *lp, int i, int stat) |
---|
438 | { /* set (change) row status */ |
---|
439 | glp_set_row_stat(lp, i, stat - LPX_BS + GLP_BS); |
---|
440 | return; |
---|
441 | } |
---|
442 | |
---|
443 | void lpx_set_col_stat(LPX *lp, int j, int stat) |
---|
444 | { /* set (change) column status */ |
---|
445 | glp_set_col_stat(lp, j, stat - LPX_BS + GLP_BS); |
---|
446 | return; |
---|
447 | } |
---|
448 | |
---|
449 | void lpx_std_basis(LPX *lp) |
---|
450 | { /* construct standard initial LP basis */ |
---|
451 | glp_std_basis(lp); |
---|
452 | return; |
---|
453 | } |
---|
454 | |
---|
455 | void lpx_adv_basis(LPX *lp) |
---|
456 | { /* construct advanced initial LP basis */ |
---|
457 | glp_adv_basis(lp, 0); |
---|
458 | return; |
---|
459 | } |
---|
460 | |
---|
461 | void lpx_cpx_basis(LPX *lp) |
---|
462 | { /* construct Bixby's initial LP basis */ |
---|
463 | glp_cpx_basis(lp); |
---|
464 | return; |
---|
465 | } |
---|
466 | |
---|
467 | static void fill_smcp(LPX *lp, glp_smcp *parm) |
---|
468 | { glp_init_smcp(parm); |
---|
469 | switch (lpx_get_int_parm(lp, LPX_K_MSGLEV)) |
---|
470 | { case 0: parm->msg_lev = GLP_MSG_OFF; break; |
---|
471 | case 1: parm->msg_lev = GLP_MSG_ERR; break; |
---|
472 | case 2: parm->msg_lev = GLP_MSG_ON; break; |
---|
473 | case 3: parm->msg_lev = GLP_MSG_ALL; break; |
---|
474 | default: xassert(lp != lp); |
---|
475 | } |
---|
476 | switch (lpx_get_int_parm(lp, LPX_K_DUAL)) |
---|
477 | { case 0: parm->meth = GLP_PRIMAL; break; |
---|
478 | case 1: parm->meth = GLP_DUAL; break; |
---|
479 | default: xassert(lp != lp); |
---|
480 | } |
---|
481 | switch (lpx_get_int_parm(lp, LPX_K_PRICE)) |
---|
482 | { case 0: parm->pricing = GLP_PT_STD; break; |
---|
483 | case 1: parm->pricing = GLP_PT_PSE; break; |
---|
484 | default: xassert(lp != lp); |
---|
485 | } |
---|
486 | if (lpx_get_real_parm(lp, LPX_K_RELAX) == 0.0) |
---|
487 | parm->r_test = GLP_RT_STD; |
---|
488 | else |
---|
489 | parm->r_test = GLP_RT_HAR; |
---|
490 | parm->tol_bnd = lpx_get_real_parm(lp, LPX_K_TOLBND); |
---|
491 | parm->tol_dj = lpx_get_real_parm(lp, LPX_K_TOLDJ); |
---|
492 | parm->tol_piv = lpx_get_real_parm(lp, LPX_K_TOLPIV); |
---|
493 | parm->obj_ll = lpx_get_real_parm(lp, LPX_K_OBJLL); |
---|
494 | parm->obj_ul = lpx_get_real_parm(lp, LPX_K_OBJUL); |
---|
495 | if (lpx_get_int_parm(lp, LPX_K_ITLIM) < 0) |
---|
496 | parm->it_lim = INT_MAX; |
---|
497 | else |
---|
498 | parm->it_lim = lpx_get_int_parm(lp, LPX_K_ITLIM); |
---|
499 | if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0) |
---|
500 | parm->tm_lim = INT_MAX; |
---|
501 | else |
---|
502 | parm->tm_lim = |
---|
503 | (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM)); |
---|
504 | parm->out_frq = lpx_get_int_parm(lp, LPX_K_OUTFRQ); |
---|
505 | parm->out_dly = |
---|
506 | (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_OUTDLY)); |
---|
507 | switch (lpx_get_int_parm(lp, LPX_K_PRESOL)) |
---|
508 | { case 0: parm->presolve = GLP_OFF; break; |
---|
509 | case 1: parm->presolve = GLP_ON; break; |
---|
510 | default: xassert(lp != lp); |
---|
511 | } |
---|
512 | return; |
---|
513 | } |
---|
514 | |
---|
515 | int lpx_simplex(LPX *lp) |
---|
516 | { /* easy-to-use driver to the simplex method */ |
---|
517 | glp_smcp parm; |
---|
518 | int ret; |
---|
519 | fill_smcp(lp, &parm); |
---|
520 | ret = glp_simplex(lp, &parm); |
---|
521 | switch (ret) |
---|
522 | { case 0: ret = LPX_E_OK; break; |
---|
523 | case GLP_EBADB: |
---|
524 | case GLP_ESING: |
---|
525 | case GLP_ECOND: |
---|
526 | case GLP_EBOUND: ret = LPX_E_FAULT; break; |
---|
527 | case GLP_EFAIL: ret = LPX_E_SING; break; |
---|
528 | case GLP_EOBJLL: ret = LPX_E_OBJLL; break; |
---|
529 | case GLP_EOBJUL: ret = LPX_E_OBJUL; break; |
---|
530 | case GLP_EITLIM: ret = LPX_E_ITLIM; break; |
---|
531 | case GLP_ETMLIM: ret = LPX_E_TMLIM; break; |
---|
532 | case GLP_ENOPFS: ret = LPX_E_NOPFS; break; |
---|
533 | case GLP_ENODFS: ret = LPX_E_NODFS; break; |
---|
534 | default: xassert(ret != ret); |
---|
535 | } |
---|
536 | return ret; |
---|
537 | } |
---|
538 | |
---|
539 | int lpx_exact(LPX *lp) |
---|
540 | { /* easy-to-use driver to the exact simplex method */ |
---|
541 | glp_smcp parm; |
---|
542 | int ret; |
---|
543 | fill_smcp(lp, &parm); |
---|
544 | ret = glp_exact(lp, &parm); |
---|
545 | switch (ret) |
---|
546 | { case 0: ret = LPX_E_OK; break; |
---|
547 | case GLP_EBADB: |
---|
548 | case GLP_ESING: |
---|
549 | case GLP_EBOUND: |
---|
550 | case GLP_EFAIL: ret = LPX_E_FAULT; break; |
---|
551 | case GLP_EITLIM: ret = LPX_E_ITLIM; break; |
---|
552 | case GLP_ETMLIM: ret = LPX_E_TMLIM; break; |
---|
553 | default: xassert(ret != ret); |
---|
554 | } |
---|
555 | return ret; |
---|
556 | } |
---|
557 | |
---|
558 | int lpx_get_status(glp_prob *lp) |
---|
559 | { /* retrieve generic status of basic solution */ |
---|
560 | int status; |
---|
561 | switch (glp_get_status(lp)) |
---|
562 | { case GLP_OPT: status = LPX_OPT; break; |
---|
563 | case GLP_FEAS: status = LPX_FEAS; break; |
---|
564 | case GLP_INFEAS: status = LPX_INFEAS; break; |
---|
565 | case GLP_NOFEAS: status = LPX_NOFEAS; break; |
---|
566 | case GLP_UNBND: status = LPX_UNBND; break; |
---|
567 | case GLP_UNDEF: status = LPX_UNDEF; break; |
---|
568 | default: xassert(lp != lp); |
---|
569 | } |
---|
570 | return status; |
---|
571 | } |
---|
572 | |
---|
573 | int lpx_get_prim_stat(glp_prob *lp) |
---|
574 | { /* retrieve status of primal basic solution */ |
---|
575 | return glp_get_prim_stat(lp) - GLP_UNDEF + LPX_P_UNDEF; |
---|
576 | } |
---|
577 | |
---|
578 | int lpx_get_dual_stat(glp_prob *lp) |
---|
579 | { /* retrieve status of dual basic solution */ |
---|
580 | return glp_get_dual_stat(lp) - GLP_UNDEF + LPX_D_UNDEF; |
---|
581 | } |
---|
582 | |
---|
583 | double lpx_get_obj_val(LPX *lp) |
---|
584 | { /* retrieve objective value (basic solution) */ |
---|
585 | return glp_get_obj_val(lp); |
---|
586 | } |
---|
587 | |
---|
588 | int lpx_get_row_stat(LPX *lp, int i) |
---|
589 | { /* retrieve row status (basic solution) */ |
---|
590 | return glp_get_row_stat(lp, i) - GLP_BS + LPX_BS; |
---|
591 | } |
---|
592 | |
---|
593 | double lpx_get_row_prim(LPX *lp, int i) |
---|
594 | { /* retrieve row primal value (basic solution) */ |
---|
595 | return glp_get_row_prim(lp, i); |
---|
596 | } |
---|
597 | |
---|
598 | double lpx_get_row_dual(LPX *lp, int i) |
---|
599 | { /* retrieve row dual value (basic solution) */ |
---|
600 | return glp_get_row_dual(lp, i); |
---|
601 | } |
---|
602 | |
---|
603 | void lpx_get_row_info(glp_prob *lp, int i, int *tagx, double *vx, |
---|
604 | double *dx) |
---|
605 | { /* obtain row solution information */ |
---|
606 | if (tagx != NULL) *tagx = lpx_get_row_stat(lp, i); |
---|
607 | if (vx != NULL) *vx = lpx_get_row_prim(lp, i); |
---|
608 | if (dx != NULL) *dx = lpx_get_row_dual(lp, i); |
---|
609 | return; |
---|
610 | } |
---|
611 | |
---|
612 | int lpx_get_col_stat(LPX *lp, int j) |
---|
613 | { /* retrieve column status (basic solution) */ |
---|
614 | return glp_get_col_stat(lp, j) - GLP_BS + LPX_BS; |
---|
615 | } |
---|
616 | |
---|
617 | double lpx_get_col_prim(LPX *lp, int j) |
---|
618 | { /* retrieve column primal value (basic solution) */ |
---|
619 | return glp_get_col_prim(lp, j); |
---|
620 | } |
---|
621 | |
---|
622 | double lpx_get_col_dual(glp_prob *lp, int j) |
---|
623 | { /* retrieve column dual value (basic solution) */ |
---|
624 | return glp_get_col_dual(lp, j); |
---|
625 | } |
---|
626 | |
---|
627 | void lpx_get_col_info(glp_prob *lp, int j, int *tagx, double *vx, |
---|
628 | double *dx) |
---|
629 | { /* obtain column solution information */ |
---|
630 | if (tagx != NULL) *tagx = lpx_get_col_stat(lp, j); |
---|
631 | if (vx != NULL) *vx = lpx_get_col_prim(lp, j); |
---|
632 | if (dx != NULL) *dx = lpx_get_col_dual(lp, j); |
---|
633 | return; |
---|
634 | } |
---|
635 | |
---|
636 | int lpx_get_ray_info(LPX *lp) |
---|
637 | { /* determine what causes primal unboundness */ |
---|
638 | return glp_get_unbnd_ray(lp); |
---|
639 | } |
---|
640 | |
---|
641 | void lpx_check_kkt(LPX *lp, int scaled, LPXKKT *kkt) |
---|
642 | { /* check Karush-Kuhn-Tucker conditions */ |
---|
643 | int ae_ind, re_ind; |
---|
644 | double ae_max, re_max; |
---|
645 | xassert(scaled == scaled); |
---|
646 | _glp_check_kkt(lp, GLP_SOL, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, |
---|
647 | &re_ind); |
---|
648 | kkt->pe_ae_max = ae_max; |
---|
649 | kkt->pe_ae_row = ae_ind; |
---|
650 | kkt->pe_re_max = re_max; |
---|
651 | kkt->pe_re_row = re_ind; |
---|
652 | if (re_max <= 1e-9) |
---|
653 | kkt->pe_quality = 'H'; |
---|
654 | else if (re_max <= 1e-6) |
---|
655 | kkt->pe_quality = 'M'; |
---|
656 | else if (re_max <= 1e-3) |
---|
657 | kkt->pe_quality = 'L'; |
---|
658 | else |
---|
659 | kkt->pe_quality = '?'; |
---|
660 | _glp_check_kkt(lp, GLP_SOL, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, |
---|
661 | &re_ind); |
---|
662 | kkt->pb_ae_max = ae_max; |
---|
663 | kkt->pb_ae_ind = ae_ind; |
---|
664 | kkt->pb_re_max = re_max; |
---|
665 | kkt->pb_re_ind = re_ind; |
---|
666 | if (re_max <= 1e-9) |
---|
667 | kkt->pb_quality = 'H'; |
---|
668 | else if (re_max <= 1e-6) |
---|
669 | kkt->pb_quality = 'M'; |
---|
670 | else if (re_max <= 1e-3) |
---|
671 | kkt->pb_quality = 'L'; |
---|
672 | else |
---|
673 | kkt->pb_quality = '?'; |
---|
674 | _glp_check_kkt(lp, GLP_SOL, GLP_KKT_DE, &ae_max, &ae_ind, &re_max, |
---|
675 | &re_ind); |
---|
676 | kkt->de_ae_max = ae_max; |
---|
677 | if (ae_ind == 0) |
---|
678 | kkt->de_ae_col = 0; |
---|
679 | else |
---|
680 | kkt->de_ae_col = ae_ind - lp->m; |
---|
681 | kkt->de_re_max = re_max; |
---|
682 | if (re_ind == 0) |
---|
683 | kkt->de_re_col = 0; |
---|
684 | else |
---|
685 | kkt->de_re_col = ae_ind - lp->m; |
---|
686 | if (re_max <= 1e-9) |
---|
687 | kkt->de_quality = 'H'; |
---|
688 | else if (re_max <= 1e-6) |
---|
689 | kkt->de_quality = 'M'; |
---|
690 | else if (re_max <= 1e-3) |
---|
691 | kkt->de_quality = 'L'; |
---|
692 | else |
---|
693 | kkt->de_quality = '?'; |
---|
694 | _glp_check_kkt(lp, GLP_SOL, GLP_KKT_DB, &ae_max, &ae_ind, &re_max, |
---|
695 | &re_ind); |
---|
696 | kkt->db_ae_max = ae_max; |
---|
697 | kkt->db_ae_ind = ae_ind; |
---|
698 | kkt->db_re_max = re_max; |
---|
699 | kkt->db_re_ind = re_ind; |
---|
700 | if (re_max <= 1e-9) |
---|
701 | kkt->db_quality = 'H'; |
---|
702 | else if (re_max <= 1e-6) |
---|
703 | kkt->db_quality = 'M'; |
---|
704 | else if (re_max <= 1e-3) |
---|
705 | kkt->db_quality = 'L'; |
---|
706 | else |
---|
707 | kkt->db_quality = '?'; |
---|
708 | kkt->cs_ae_max = 0.0, kkt->cs_ae_ind = 0; |
---|
709 | kkt->cs_re_max = 0.0, kkt->cs_re_ind = 0; |
---|
710 | kkt->cs_quality = 'H'; |
---|
711 | return; |
---|
712 | } |
---|
713 | |
---|
714 | int lpx_warm_up(LPX *lp) |
---|
715 | { /* "warm up" LP basis */ |
---|
716 | int ret; |
---|
717 | ret = glp_warm_up(lp); |
---|
718 | if (ret == 0) |
---|
719 | ret = LPX_E_OK; |
---|
720 | else if (ret == GLP_EBADB) |
---|
721 | ret = LPX_E_BADB; |
---|
722 | else if (ret == GLP_ESING) |
---|
723 | ret = LPX_E_SING; |
---|
724 | else if (ret == GLP_ECOND) |
---|
725 | ret = LPX_E_SING; |
---|
726 | else |
---|
727 | xassert(ret != ret); |
---|
728 | return ret; |
---|
729 | } |
---|
730 | |
---|
731 | int lpx_eval_tab_row(LPX *lp, int k, int ind[], double val[]) |
---|
732 | { /* compute row of the simplex tableau */ |
---|
733 | return glp_eval_tab_row(lp, k, ind, val); |
---|
734 | } |
---|
735 | |
---|
736 | int lpx_eval_tab_col(LPX *lp, int k, int ind[], double val[]) |
---|
737 | { /* compute column of the simplex tableau */ |
---|
738 | return glp_eval_tab_col(lp, k, ind, val); |
---|
739 | } |
---|
740 | |
---|
741 | int lpx_transform_row(LPX *lp, int len, int ind[], double val[]) |
---|
742 | { /* transform explicitly specified row */ |
---|
743 | return glp_transform_row(lp, len, ind, val); |
---|
744 | } |
---|
745 | |
---|
746 | int lpx_transform_col(LPX *lp, int len, int ind[], double val[]) |
---|
747 | { /* transform explicitly specified column */ |
---|
748 | return glp_transform_col(lp, len, ind, val); |
---|
749 | } |
---|
750 | |
---|
751 | int lpx_prim_ratio_test(LPX *lp, int len, const int ind[], |
---|
752 | const double val[], int how, double tol) |
---|
753 | { /* perform primal ratio test */ |
---|
754 | int piv; |
---|
755 | piv = glp_prim_rtest(lp, len, ind, val, how, tol); |
---|
756 | xassert(0 <= piv && piv <= len); |
---|
757 | return piv == 0 ? 0 : ind[piv]; |
---|
758 | } |
---|
759 | |
---|
760 | int lpx_dual_ratio_test(LPX *lp, int len, const int ind[], |
---|
761 | const double val[], int how, double tol) |
---|
762 | { /* perform dual ratio test */ |
---|
763 | int piv; |
---|
764 | piv = glp_dual_rtest(lp, len, ind, val, how, tol); |
---|
765 | xassert(0 <= piv && piv <= len); |
---|
766 | return piv == 0 ? 0 : ind[piv]; |
---|
767 | } |
---|
768 | |
---|
769 | int lpx_interior(LPX *lp) |
---|
770 | { /* easy-to-use driver to the interior-point method */ |
---|
771 | int ret; |
---|
772 | ret = glp_interior(lp, NULL); |
---|
773 | switch (ret) |
---|
774 | { case 0: ret = LPX_E_OK; break; |
---|
775 | case GLP_EFAIL: ret = LPX_E_FAULT; break; |
---|
776 | case GLP_ENOFEAS: ret = LPX_E_NOFEAS; break; |
---|
777 | case GLP_ENOCVG: ret = LPX_E_NOCONV; break; |
---|
778 | case GLP_EITLIM: ret = LPX_E_ITLIM; break; |
---|
779 | case GLP_EINSTAB: ret = LPX_E_INSTAB; break; |
---|
780 | default: xassert(ret != ret); |
---|
781 | } |
---|
782 | return ret; |
---|
783 | } |
---|
784 | |
---|
785 | int lpx_ipt_status(glp_prob *lp) |
---|
786 | { /* retrieve status of interior-point solution */ |
---|
787 | int status; |
---|
788 | switch (glp_ipt_status(lp)) |
---|
789 | { case GLP_UNDEF: status = LPX_T_UNDEF; break; |
---|
790 | case GLP_OPT: status = LPX_T_OPT; break; |
---|
791 | default: xassert(lp != lp); |
---|
792 | } |
---|
793 | return status; |
---|
794 | } |
---|
795 | |
---|
796 | double lpx_ipt_obj_val(LPX *lp) |
---|
797 | { /* retrieve objective value (interior point) */ |
---|
798 | return glp_ipt_obj_val(lp); |
---|
799 | } |
---|
800 | |
---|
801 | double lpx_ipt_row_prim(LPX *lp, int i) |
---|
802 | { /* retrieve row primal value (interior point) */ |
---|
803 | return glp_ipt_row_prim(lp, i); |
---|
804 | } |
---|
805 | |
---|
806 | double lpx_ipt_row_dual(LPX *lp, int i) |
---|
807 | { /* retrieve row dual value (interior point) */ |
---|
808 | return glp_ipt_row_dual(lp, i); |
---|
809 | } |
---|
810 | |
---|
811 | double lpx_ipt_col_prim(LPX *lp, int j) |
---|
812 | { /* retrieve column primal value (interior point) */ |
---|
813 | return glp_ipt_col_prim(lp, j); |
---|
814 | } |
---|
815 | |
---|
816 | double lpx_ipt_col_dual(LPX *lp, int j) |
---|
817 | { /* retrieve column dual value (interior point) */ |
---|
818 | return glp_ipt_col_dual(lp, j); |
---|
819 | } |
---|
820 | |
---|
821 | void lpx_set_class(LPX *lp, int klass) |
---|
822 | { /* set problem class */ |
---|
823 | xassert(lp == lp); |
---|
824 | if (!(klass == LPX_LP || klass == LPX_MIP)) |
---|
825 | xerror("lpx_set_class: invalid problem class\n"); |
---|
826 | return; |
---|
827 | } |
---|
828 | |
---|
829 | int lpx_get_class(LPX *lp) |
---|
830 | { /* determine problem klass */ |
---|
831 | return glp_get_num_int(lp) == 0 ? LPX_LP : LPX_MIP; |
---|
832 | } |
---|
833 | |
---|
834 | void lpx_set_col_kind(LPX *lp, int j, int kind) |
---|
835 | { /* set (change) column kind */ |
---|
836 | glp_set_col_kind(lp, j, kind - LPX_CV + GLP_CV); |
---|
837 | return; |
---|
838 | } |
---|
839 | |
---|
840 | int lpx_get_col_kind(LPX *lp, int j) |
---|
841 | { /* retrieve column kind */ |
---|
842 | return glp_get_col_kind(lp, j) == GLP_CV ? LPX_CV : LPX_IV; |
---|
843 | } |
---|
844 | |
---|
845 | int lpx_get_num_int(LPX *lp) |
---|
846 | { /* retrieve number of integer columns */ |
---|
847 | return glp_get_num_int(lp); |
---|
848 | } |
---|
849 | |
---|
850 | int lpx_get_num_bin(LPX *lp) |
---|
851 | { /* retrieve number of binary columns */ |
---|
852 | return glp_get_num_bin(lp); |
---|
853 | } |
---|
854 | |
---|
855 | static int solve_mip(LPX *lp, int presolve) |
---|
856 | { glp_iocp parm; |
---|
857 | int ret; |
---|
858 | glp_init_iocp(&parm); |
---|
859 | switch (lpx_get_int_parm(lp, LPX_K_MSGLEV)) |
---|
860 | { case 0: parm.msg_lev = GLP_MSG_OFF; break; |
---|
861 | case 1: parm.msg_lev = GLP_MSG_ERR; break; |
---|
862 | case 2: parm.msg_lev = GLP_MSG_ON; break; |
---|
863 | case 3: parm.msg_lev = GLP_MSG_ALL; break; |
---|
864 | default: xassert(lp != lp); |
---|
865 | } |
---|
866 | switch (lpx_get_int_parm(lp, LPX_K_BRANCH)) |
---|
867 | { case 0: parm.br_tech = GLP_BR_FFV; break; |
---|
868 | case 1: parm.br_tech = GLP_BR_LFV; break; |
---|
869 | case 2: parm.br_tech = GLP_BR_DTH; break; |
---|
870 | case 3: parm.br_tech = GLP_BR_MFV; break; |
---|
871 | default: xassert(lp != lp); |
---|
872 | } |
---|
873 | switch (lpx_get_int_parm(lp, LPX_K_BTRACK)) |
---|
874 | { case 0: parm.bt_tech = GLP_BT_DFS; break; |
---|
875 | case 1: parm.bt_tech = GLP_BT_BFS; break; |
---|
876 | case 2: parm.bt_tech = GLP_BT_BPH; break; |
---|
877 | case 3: parm.bt_tech = GLP_BT_BLB; break; |
---|
878 | default: xassert(lp != lp); |
---|
879 | } |
---|
880 | parm.tol_int = lpx_get_real_parm(lp, LPX_K_TOLINT); |
---|
881 | parm.tol_obj = lpx_get_real_parm(lp, LPX_K_TOLOBJ); |
---|
882 | if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0 || |
---|
883 | lpx_get_real_parm(lp, LPX_K_TMLIM) > 1e6) |
---|
884 | parm.tm_lim = INT_MAX; |
---|
885 | else |
---|
886 | parm.tm_lim = |
---|
887 | (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM)); |
---|
888 | parm.mip_gap = lpx_get_real_parm(lp, LPX_K_MIPGAP); |
---|
889 | if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_GOMORY) |
---|
890 | parm.gmi_cuts = GLP_ON; |
---|
891 | else |
---|
892 | parm.gmi_cuts = GLP_OFF; |
---|
893 | if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_MIR) |
---|
894 | parm.mir_cuts = GLP_ON; |
---|
895 | else |
---|
896 | parm.mir_cuts = GLP_OFF; |
---|
897 | if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_COVER) |
---|
898 | parm.cov_cuts = GLP_ON; |
---|
899 | else |
---|
900 | parm.cov_cuts = GLP_OFF; |
---|
901 | if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_CLIQUE) |
---|
902 | parm.clq_cuts = GLP_ON; |
---|
903 | else |
---|
904 | parm.clq_cuts = GLP_OFF; |
---|
905 | parm.presolve = presolve; |
---|
906 | if (lpx_get_int_parm(lp, LPX_K_BINARIZE)) |
---|
907 | parm.binarize = GLP_ON; |
---|
908 | ret = glp_intopt(lp, &parm); |
---|
909 | switch (ret) |
---|
910 | { case 0: ret = LPX_E_OK; break; |
---|
911 | case GLP_ENOPFS: ret = LPX_E_NOPFS; break; |
---|
912 | case GLP_ENODFS: ret = LPX_E_NODFS; break; |
---|
913 | case GLP_EBOUND: |
---|
914 | case GLP_EROOT: ret = LPX_E_FAULT; break; |
---|
915 | case GLP_EFAIL: ret = LPX_E_SING; break; |
---|
916 | case GLP_EMIPGAP: ret = LPX_E_MIPGAP; break; |
---|
917 | case GLP_ETMLIM: ret = LPX_E_TMLIM; break; |
---|
918 | default: xassert(ret != ret); |
---|
919 | } |
---|
920 | return ret; |
---|
921 | } |
---|
922 | |
---|
923 | int lpx_integer(LPX *lp) |
---|
924 | { /* easy-to-use driver to the branch-and-bound method */ |
---|
925 | return solve_mip(lp, GLP_OFF); |
---|
926 | } |
---|
927 | |
---|
928 | int lpx_intopt(LPX *lp) |
---|
929 | { /* easy-to-use driver to the branch-and-bound method */ |
---|
930 | return solve_mip(lp, GLP_ON); |
---|
931 | } |
---|
932 | |
---|
933 | int lpx_mip_status(glp_prob *lp) |
---|
934 | { /* retrieve status of MIP solution */ |
---|
935 | int status; |
---|
936 | switch (glp_mip_status(lp)) |
---|
937 | { case GLP_UNDEF: status = LPX_I_UNDEF; break; |
---|
938 | case GLP_OPT: status = LPX_I_OPT; break; |
---|
939 | case GLP_FEAS: status = LPX_I_FEAS; break; |
---|
940 | case GLP_NOFEAS: status = LPX_I_NOFEAS; break; |
---|
941 | default: xassert(lp != lp); |
---|
942 | } |
---|
943 | return status; |
---|
944 | } |
---|
945 | |
---|
946 | double lpx_mip_obj_val(LPX *lp) |
---|
947 | { /* retrieve objective value (MIP solution) */ |
---|
948 | return glp_mip_obj_val(lp); |
---|
949 | } |
---|
950 | |
---|
951 | double lpx_mip_row_val(LPX *lp, int i) |
---|
952 | { /* retrieve row value (MIP solution) */ |
---|
953 | return glp_mip_row_val(lp, i); |
---|
954 | } |
---|
955 | |
---|
956 | double lpx_mip_col_val(LPX *lp, int j) |
---|
957 | { /* retrieve column value (MIP solution) */ |
---|
958 | return glp_mip_col_val(lp, j); |
---|
959 | } |
---|
960 | |
---|
961 | void lpx_check_int(LPX *lp, LPXKKT *kkt) |
---|
962 | { /* check integer feasibility conditions */ |
---|
963 | int ae_ind, re_ind; |
---|
964 | double ae_max, re_max; |
---|
965 | _glp_check_kkt(lp, GLP_MIP, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, |
---|
966 | &re_ind); |
---|
967 | kkt->pe_ae_max = ae_max; |
---|
968 | kkt->pe_ae_row = ae_ind; |
---|
969 | kkt->pe_re_max = re_max; |
---|
970 | kkt->pe_re_row = re_ind; |
---|
971 | if (re_max <= 1e-9) |
---|
972 | kkt->pe_quality = 'H'; |
---|
973 | else if (re_max <= 1e-6) |
---|
974 | kkt->pe_quality = 'M'; |
---|
975 | else if (re_max <= 1e-3) |
---|
976 | kkt->pe_quality = 'L'; |
---|
977 | else |
---|
978 | kkt->pe_quality = '?'; |
---|
979 | _glp_check_kkt(lp, GLP_MIP, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, |
---|
980 | &re_ind); |
---|
981 | kkt->pb_ae_max = ae_max; |
---|
982 | kkt->pb_ae_ind = ae_ind; |
---|
983 | kkt->pb_re_max = re_max; |
---|
984 | kkt->pb_re_ind = re_ind; |
---|
985 | if (re_max <= 1e-9) |
---|
986 | kkt->pb_quality = 'H'; |
---|
987 | else if (re_max <= 1e-6) |
---|
988 | kkt->pb_quality = 'M'; |
---|
989 | else if (re_max <= 1e-3) |
---|
990 | kkt->pb_quality = 'L'; |
---|
991 | else |
---|
992 | kkt->pb_quality = '?'; |
---|
993 | return; |
---|
994 | } |
---|
995 | |
---|
996 | #if 1 /* 17/XI-2009 */ |
---|
997 | static void reset_parms(LPX *lp) |
---|
998 | { /* reset control parameters to default values */ |
---|
999 | struct LPXCPS *cps = lp->parms; |
---|
1000 | xassert(cps != NULL); |
---|
1001 | cps->msg_lev = 3; |
---|
1002 | cps->scale = 1; |
---|
1003 | cps->dual = 0; |
---|
1004 | cps->price = 1; |
---|
1005 | cps->relax = 0.07; |
---|
1006 | cps->tol_bnd = 1e-7; |
---|
1007 | cps->tol_dj = 1e-7; |
---|
1008 | cps->tol_piv = 1e-9; |
---|
1009 | cps->round = 0; |
---|
1010 | cps->obj_ll = -DBL_MAX; |
---|
1011 | cps->obj_ul = +DBL_MAX; |
---|
1012 | cps->it_lim = -1; |
---|
1013 | #if 0 /* 02/XII-2010 */ |
---|
1014 | lp->it_cnt = 0; |
---|
1015 | #endif |
---|
1016 | cps->tm_lim = -1.0; |
---|
1017 | cps->out_frq = 200; |
---|
1018 | cps->out_dly = 0.0; |
---|
1019 | cps->branch = 2; |
---|
1020 | cps->btrack = 3; |
---|
1021 | cps->tol_int = 1e-5; |
---|
1022 | cps->tol_obj = 1e-7; |
---|
1023 | cps->mps_info = 1; |
---|
1024 | cps->mps_obj = 2; |
---|
1025 | cps->mps_orig = 0; |
---|
1026 | cps->mps_wide = 1; |
---|
1027 | cps->mps_free = 0; |
---|
1028 | cps->mps_skip = 0; |
---|
1029 | cps->lpt_orig = 0; |
---|
1030 | cps->presol = 0; |
---|
1031 | cps->binarize = 0; |
---|
1032 | cps->use_cuts = 0; |
---|
1033 | cps->mip_gap = 0.0; |
---|
1034 | return; |
---|
1035 | } |
---|
1036 | #endif |
---|
1037 | |
---|
1038 | #if 1 /* 17/XI-2009 */ |
---|
1039 | static struct LPXCPS *access_parms(LPX *lp) |
---|
1040 | { /* allocate and initialize control parameters, if necessary */ |
---|
1041 | if (lp->parms == NULL) |
---|
1042 | { lp->parms = xmalloc(sizeof(struct LPXCPS)); |
---|
1043 | reset_parms(lp); |
---|
1044 | } |
---|
1045 | return lp->parms; |
---|
1046 | } |
---|
1047 | #endif |
---|
1048 | |
---|
1049 | #if 1 /* 17/XI-2009 */ |
---|
1050 | void lpx_reset_parms(LPX *lp) |
---|
1051 | { /* reset control parameters to default values */ |
---|
1052 | access_parms(lp); |
---|
1053 | reset_parms(lp); |
---|
1054 | return; |
---|
1055 | } |
---|
1056 | #endif |
---|
1057 | |
---|
1058 | void lpx_set_int_parm(LPX *lp, int parm, int val) |
---|
1059 | { /* set (change) integer control parameter */ |
---|
1060 | #if 0 /* 17/XI-2009 */ |
---|
1061 | struct LPXCPS *cps = lp->cps; |
---|
1062 | #else |
---|
1063 | struct LPXCPS *cps = access_parms(lp); |
---|
1064 | #endif |
---|
1065 | switch (parm) |
---|
1066 | { case LPX_K_MSGLEV: |
---|
1067 | if (!(0 <= val && val <= 3)) |
---|
1068 | xerror("lpx_set_int_parm: MSGLEV = %d; invalid value\n", |
---|
1069 | val); |
---|
1070 | cps->msg_lev = val; |
---|
1071 | break; |
---|
1072 | case LPX_K_SCALE: |
---|
1073 | if (!(0 <= val && val <= 3)) |
---|
1074 | xerror("lpx_set_int_parm: SCALE = %d; invalid value\n", |
---|
1075 | val); |
---|
1076 | cps->scale = val; |
---|
1077 | break; |
---|
1078 | case LPX_K_DUAL: |
---|
1079 | if (!(val == 0 || val == 1)) |
---|
1080 | xerror("lpx_set_int_parm: DUAL = %d; invalid value\n", |
---|
1081 | val); |
---|
1082 | cps->dual = val; |
---|
1083 | break; |
---|
1084 | case LPX_K_PRICE: |
---|
1085 | if (!(val == 0 || val == 1)) |
---|
1086 | xerror("lpx_set_int_parm: PRICE = %d; invalid value\n", |
---|
1087 | val); |
---|
1088 | cps->price = val; |
---|
1089 | break; |
---|
1090 | case LPX_K_ROUND: |
---|
1091 | if (!(val == 0 || val == 1)) |
---|
1092 | xerror("lpx_set_int_parm: ROUND = %d; invalid value\n", |
---|
1093 | val); |
---|
1094 | cps->round = val; |
---|
1095 | break; |
---|
1096 | case LPX_K_ITLIM: |
---|
1097 | cps->it_lim = val; |
---|
1098 | break; |
---|
1099 | case LPX_K_ITCNT: |
---|
1100 | lp->it_cnt = val; |
---|
1101 | break; |
---|
1102 | case LPX_K_OUTFRQ: |
---|
1103 | if (!(val > 0)) |
---|
1104 | xerror("lpx_set_int_parm: OUTFRQ = %d; invalid value\n", |
---|
1105 | val); |
---|
1106 | cps->out_frq = val; |
---|
1107 | break; |
---|
1108 | case LPX_K_BRANCH: |
---|
1109 | if (!(val == 0 || val == 1 || val == 2 || val == 3)) |
---|
1110 | xerror("lpx_set_int_parm: BRANCH = %d; invalid value\n", |
---|
1111 | val); |
---|
1112 | cps->branch = val; |
---|
1113 | break; |
---|
1114 | case LPX_K_BTRACK: |
---|
1115 | if (!(val == 0 || val == 1 || val == 2 || val == 3)) |
---|
1116 | xerror("lpx_set_int_parm: BTRACK = %d; invalid value\n", |
---|
1117 | val); |
---|
1118 | cps->btrack = val; |
---|
1119 | break; |
---|
1120 | case LPX_K_MPSINFO: |
---|
1121 | if (!(val == 0 || val == 1)) |
---|
1122 | xerror("lpx_set_int_parm: MPSINFO = %d; invalid value\n", |
---|
1123 | val); |
---|
1124 | cps->mps_info = val; |
---|
1125 | break; |
---|
1126 | case LPX_K_MPSOBJ: |
---|
1127 | if (!(val == 0 || val == 1 || val == 2)) |
---|
1128 | xerror("lpx_set_int_parm: MPSOBJ = %d; invalid value\n", |
---|
1129 | val); |
---|
1130 | cps->mps_obj = val; |
---|
1131 | break; |
---|
1132 | case LPX_K_MPSORIG: |
---|
1133 | if (!(val == 0 || val == 1)) |
---|
1134 | xerror("lpx_set_int_parm: MPSORIG = %d; invalid value\n", |
---|
1135 | val); |
---|
1136 | cps->mps_orig = val; |
---|
1137 | break; |
---|
1138 | case LPX_K_MPSWIDE: |
---|
1139 | if (!(val == 0 || val == 1)) |
---|
1140 | xerror("lpx_set_int_parm: MPSWIDE = %d; invalid value\n", |
---|
1141 | val); |
---|
1142 | cps->mps_wide = val; |
---|
1143 | break; |
---|
1144 | case LPX_K_MPSFREE: |
---|
1145 | if (!(val == 0 || val == 1)) |
---|
1146 | xerror("lpx_set_int_parm: MPSFREE = %d; invalid value\n", |
---|
1147 | val); |
---|
1148 | cps->mps_free = val; |
---|
1149 | break; |
---|
1150 | case LPX_K_MPSSKIP: |
---|
1151 | if (!(val == 0 || val == 1)) |
---|
1152 | xerror("lpx_set_int_parm: MPSSKIP = %d; invalid value\n", |
---|
1153 | val); |
---|
1154 | cps->mps_skip = val; |
---|
1155 | break; |
---|
1156 | case LPX_K_LPTORIG: |
---|
1157 | if (!(val == 0 || val == 1)) |
---|
1158 | xerror("lpx_set_int_parm: LPTORIG = %d; invalid value\n", |
---|
1159 | val); |
---|
1160 | cps->lpt_orig = val; |
---|
1161 | break; |
---|
1162 | case LPX_K_PRESOL: |
---|
1163 | if (!(val == 0 || val == 1)) |
---|
1164 | xerror("lpx_set_int_parm: PRESOL = %d; invalid value\n", |
---|
1165 | val); |
---|
1166 | cps->presol = val; |
---|
1167 | break; |
---|
1168 | case LPX_K_BINARIZE: |
---|
1169 | if (!(val == 0 || val == 1)) |
---|
1170 | xerror("lpx_set_int_parm: BINARIZE = %d; invalid value\n" |
---|
1171 | , val); |
---|
1172 | cps->binarize = val; |
---|
1173 | break; |
---|
1174 | case LPX_K_USECUTS: |
---|
1175 | if (val & ~LPX_C_ALL) |
---|
1176 | xerror("lpx_set_int_parm: USECUTS = 0x%X; invalid value\n", |
---|
1177 | val); |
---|
1178 | cps->use_cuts = val; |
---|
1179 | break; |
---|
1180 | case LPX_K_BFTYPE: |
---|
1181 | #if 0 |
---|
1182 | if (!(1 <= val && val <= 3)) |
---|
1183 | xerror("lpx_set_int_parm: BFTYPE = %d; invalid value\n", |
---|
1184 | val); |
---|
1185 | cps->bf_type = val; |
---|
1186 | #else |
---|
1187 | { glp_bfcp parm; |
---|
1188 | glp_get_bfcp(lp, &parm); |
---|
1189 | switch (val) |
---|
1190 | { case 1: |
---|
1191 | parm.type = GLP_BF_FT; break; |
---|
1192 | case 2: |
---|
1193 | parm.type = GLP_BF_BG; break; |
---|
1194 | case 3: |
---|
1195 | parm.type = GLP_BF_GR; break; |
---|
1196 | default: |
---|
1197 | xerror("lpx_set_int_parm: BFTYPE = %d; invalid val" |
---|
1198 | "ue\n", val); |
---|
1199 | } |
---|
1200 | glp_set_bfcp(lp, &parm); |
---|
1201 | } |
---|
1202 | #endif |
---|
1203 | break; |
---|
1204 | default: |
---|
1205 | xerror("lpx_set_int_parm: parm = %d; invalid parameter\n", |
---|
1206 | parm); |
---|
1207 | } |
---|
1208 | return; |
---|
1209 | } |
---|
1210 | |
---|
1211 | int lpx_get_int_parm(LPX *lp, int parm) |
---|
1212 | { /* query integer control parameter */ |
---|
1213 | #if 0 /* 17/XI-2009 */ |
---|
1214 | struct LPXCPS *cps = lp->cps; |
---|
1215 | #else |
---|
1216 | struct LPXCPS *cps = access_parms(lp); |
---|
1217 | #endif |
---|
1218 | int val = 0; |
---|
1219 | switch (parm) |
---|
1220 | { case LPX_K_MSGLEV: |
---|
1221 | val = cps->msg_lev; break; |
---|
1222 | case LPX_K_SCALE: |
---|
1223 | val = cps->scale; break; |
---|
1224 | case LPX_K_DUAL: |
---|
1225 | val = cps->dual; break; |
---|
1226 | case LPX_K_PRICE: |
---|
1227 | val = cps->price; break; |
---|
1228 | case LPX_K_ROUND: |
---|
1229 | val = cps->round; break; |
---|
1230 | case LPX_K_ITLIM: |
---|
1231 | val = cps->it_lim; break; |
---|
1232 | case LPX_K_ITCNT: |
---|
1233 | val = lp->it_cnt; break; |
---|
1234 | case LPX_K_OUTFRQ: |
---|
1235 | val = cps->out_frq; break; |
---|
1236 | case LPX_K_BRANCH: |
---|
1237 | val = cps->branch; break; |
---|
1238 | case LPX_K_BTRACK: |
---|
1239 | val = cps->btrack; break; |
---|
1240 | case LPX_K_MPSINFO: |
---|
1241 | val = cps->mps_info; break; |
---|
1242 | case LPX_K_MPSOBJ: |
---|
1243 | val = cps->mps_obj; break; |
---|
1244 | case LPX_K_MPSORIG: |
---|
1245 | val = cps->mps_orig; break; |
---|
1246 | case LPX_K_MPSWIDE: |
---|
1247 | val = cps->mps_wide; break; |
---|
1248 | case LPX_K_MPSFREE: |
---|
1249 | val = cps->mps_free; break; |
---|
1250 | case LPX_K_MPSSKIP: |
---|
1251 | val = cps->mps_skip; break; |
---|
1252 | case LPX_K_LPTORIG: |
---|
1253 | val = cps->lpt_orig; break; |
---|
1254 | case LPX_K_PRESOL: |
---|
1255 | val = cps->presol; break; |
---|
1256 | case LPX_K_BINARIZE: |
---|
1257 | val = cps->binarize; break; |
---|
1258 | case LPX_K_USECUTS: |
---|
1259 | val = cps->use_cuts; break; |
---|
1260 | case LPX_K_BFTYPE: |
---|
1261 | #if 0 |
---|
1262 | val = cps->bf_type; break; |
---|
1263 | #else |
---|
1264 | { glp_bfcp parm; |
---|
1265 | glp_get_bfcp(lp, &parm); |
---|
1266 | switch (parm.type) |
---|
1267 | { case GLP_BF_FT: |
---|
1268 | val = 1; break; |
---|
1269 | case GLP_BF_BG: |
---|
1270 | val = 2; break; |
---|
1271 | case GLP_BF_GR: |
---|
1272 | val = 3; break; |
---|
1273 | default: |
---|
1274 | xassert(lp != lp); |
---|
1275 | } |
---|
1276 | } |
---|
1277 | break; |
---|
1278 | #endif |
---|
1279 | default: |
---|
1280 | xerror("lpx_get_int_parm: parm = %d; invalid parameter\n", |
---|
1281 | parm); |
---|
1282 | } |
---|
1283 | return val; |
---|
1284 | } |
---|
1285 | |
---|
1286 | void lpx_set_real_parm(LPX *lp, int parm, double val) |
---|
1287 | { /* set (change) real control parameter */ |
---|
1288 | #if 0 /* 17/XI-2009 */ |
---|
1289 | struct LPXCPS *cps = lp->cps; |
---|
1290 | #else |
---|
1291 | struct LPXCPS *cps = access_parms(lp); |
---|
1292 | #endif |
---|
1293 | switch (parm) |
---|
1294 | { case LPX_K_RELAX: |
---|
1295 | if (!(0.0 <= val && val <= 1.0)) |
---|
1296 | xerror("lpx_set_real_parm: RELAX = %g; invalid value\n", |
---|
1297 | val); |
---|
1298 | cps->relax = val; |
---|
1299 | break; |
---|
1300 | case LPX_K_TOLBND: |
---|
1301 | if (!(DBL_EPSILON <= val && val <= 0.001)) |
---|
1302 | xerror("lpx_set_real_parm: TOLBND = %g; invalid value\n", |
---|
1303 | val); |
---|
1304 | #if 0 |
---|
1305 | if (cps->tol_bnd > val) |
---|
1306 | { /* invalidate the basic solution */ |
---|
1307 | lp->p_stat = LPX_P_UNDEF; |
---|
1308 | lp->d_stat = LPX_D_UNDEF; |
---|
1309 | } |
---|
1310 | #endif |
---|
1311 | cps->tol_bnd = val; |
---|
1312 | break; |
---|
1313 | case LPX_K_TOLDJ: |
---|
1314 | if (!(DBL_EPSILON <= val && val <= 0.001)) |
---|
1315 | xerror("lpx_set_real_parm: TOLDJ = %g; invalid value\n", |
---|
1316 | val); |
---|
1317 | #if 0 |
---|
1318 | if (cps->tol_dj > val) |
---|
1319 | { /* invalidate the basic solution */ |
---|
1320 | lp->p_stat = LPX_P_UNDEF; |
---|
1321 | lp->d_stat = LPX_D_UNDEF; |
---|
1322 | } |
---|
1323 | #endif |
---|
1324 | cps->tol_dj = val; |
---|
1325 | break; |
---|
1326 | case LPX_K_TOLPIV: |
---|
1327 | if (!(DBL_EPSILON <= val && val <= 0.001)) |
---|
1328 | xerror("lpx_set_real_parm: TOLPIV = %g; invalid value\n", |
---|
1329 | val); |
---|
1330 | cps->tol_piv = val; |
---|
1331 | break; |
---|
1332 | case LPX_K_OBJLL: |
---|
1333 | cps->obj_ll = val; |
---|
1334 | break; |
---|
1335 | case LPX_K_OBJUL: |
---|
1336 | cps->obj_ul = val; |
---|
1337 | break; |
---|
1338 | case LPX_K_TMLIM: |
---|
1339 | cps->tm_lim = val; |
---|
1340 | break; |
---|
1341 | case LPX_K_OUTDLY: |
---|
1342 | cps->out_dly = val; |
---|
1343 | break; |
---|
1344 | case LPX_K_TOLINT: |
---|
1345 | if (!(DBL_EPSILON <= val && val <= 0.001)) |
---|
1346 | xerror("lpx_set_real_parm: TOLINT = %g; invalid value\n", |
---|
1347 | val); |
---|
1348 | cps->tol_int = val; |
---|
1349 | break; |
---|
1350 | case LPX_K_TOLOBJ: |
---|
1351 | if (!(DBL_EPSILON <= val && val <= 0.001)) |
---|
1352 | xerror("lpx_set_real_parm: TOLOBJ = %g; invalid value\n", |
---|
1353 | val); |
---|
1354 | cps->tol_obj = val; |
---|
1355 | break; |
---|
1356 | case LPX_K_MIPGAP: |
---|
1357 | if (val < 0.0) |
---|
1358 | xerror("lpx_set_real_parm: MIPGAP = %g; invalid value\n", |
---|
1359 | val); |
---|
1360 | cps->mip_gap = val; |
---|
1361 | break; |
---|
1362 | default: |
---|
1363 | xerror("lpx_set_real_parm: parm = %d; invalid parameter\n", |
---|
1364 | parm); |
---|
1365 | } |
---|
1366 | return; |
---|
1367 | } |
---|
1368 | |
---|
1369 | double lpx_get_real_parm(LPX *lp, int parm) |
---|
1370 | { /* query real control parameter */ |
---|
1371 | #if 0 /* 17/XI-2009 */ |
---|
1372 | struct LPXCPS *cps = lp->cps; |
---|
1373 | #else |
---|
1374 | struct LPXCPS *cps = access_parms(lp); |
---|
1375 | #endif |
---|
1376 | double val = 0.0; |
---|
1377 | switch (parm) |
---|
1378 | { case LPX_K_RELAX: |
---|
1379 | val = cps->relax; |
---|
1380 | break; |
---|
1381 | case LPX_K_TOLBND: |
---|
1382 | val = cps->tol_bnd; |
---|
1383 | break; |
---|
1384 | case LPX_K_TOLDJ: |
---|
1385 | val = cps->tol_dj; |
---|
1386 | break; |
---|
1387 | case LPX_K_TOLPIV: |
---|
1388 | val = cps->tol_piv; |
---|
1389 | break; |
---|
1390 | case LPX_K_OBJLL: |
---|
1391 | val = cps->obj_ll; |
---|
1392 | break; |
---|
1393 | case LPX_K_OBJUL: |
---|
1394 | val = cps->obj_ul; |
---|
1395 | break; |
---|
1396 | case LPX_K_TMLIM: |
---|
1397 | val = cps->tm_lim; |
---|
1398 | break; |
---|
1399 | case LPX_K_OUTDLY: |
---|
1400 | val = cps->out_dly; |
---|
1401 | break; |
---|
1402 | case LPX_K_TOLINT: |
---|
1403 | val = cps->tol_int; |
---|
1404 | break; |
---|
1405 | case LPX_K_TOLOBJ: |
---|
1406 | val = cps->tol_obj; |
---|
1407 | break; |
---|
1408 | case LPX_K_MIPGAP: |
---|
1409 | val = cps->mip_gap; |
---|
1410 | break; |
---|
1411 | default: |
---|
1412 | xerror("lpx_get_real_parm: parm = %d; invalid parameter\n", |
---|
1413 | parm); |
---|
1414 | } |
---|
1415 | return val; |
---|
1416 | } |
---|
1417 | |
---|
1418 | LPX *lpx_read_mps(const char *fname) |
---|
1419 | { /* read problem data in fixed MPS format */ |
---|
1420 | LPX *lp = lpx_create_prob(); |
---|
1421 | if (glp_read_mps(lp, GLP_MPS_DECK, NULL, fname)) |
---|
1422 | lpx_delete_prob(lp), lp = NULL; |
---|
1423 | return lp; |
---|
1424 | } |
---|
1425 | |
---|
1426 | int lpx_write_mps(LPX *lp, const char *fname) |
---|
1427 | { /* write problem data in fixed MPS format */ |
---|
1428 | return glp_write_mps(lp, GLP_MPS_DECK, NULL, fname); |
---|
1429 | } |
---|
1430 | |
---|
1431 | int lpx_read_bas(LPX *lp, const char *fname) |
---|
1432 | { /* read LP basis in fixed MPS format */ |
---|
1433 | #if 0 /* 13/IV-2009 */ |
---|
1434 | return read_bas(lp, fname); |
---|
1435 | #else |
---|
1436 | xassert(lp == lp); |
---|
1437 | xassert(fname == fname); |
---|
1438 | xerror("lpx_read_bas: operation not supported\n"); |
---|
1439 | return 0; |
---|
1440 | #endif |
---|
1441 | } |
---|
1442 | |
---|
1443 | int lpx_write_bas(LPX *lp, const char *fname) |
---|
1444 | { /* write LP basis in fixed MPS format */ |
---|
1445 | #if 0 /* 13/IV-2009 */ |
---|
1446 | return write_bas(lp, fname); |
---|
1447 | #else |
---|
1448 | xassert(lp == lp); |
---|
1449 | xassert(fname == fname); |
---|
1450 | xerror("lpx_write_bas: operation not supported\n"); |
---|
1451 | return 0; |
---|
1452 | #endif |
---|
1453 | } |
---|
1454 | |
---|
1455 | LPX *lpx_read_freemps(const char *fname) |
---|
1456 | { /* read problem data in free MPS format */ |
---|
1457 | LPX *lp = lpx_create_prob(); |
---|
1458 | if (glp_read_mps(lp, GLP_MPS_FILE, NULL, fname)) |
---|
1459 | lpx_delete_prob(lp), lp = NULL; |
---|
1460 | return lp; |
---|
1461 | } |
---|
1462 | |
---|
1463 | int lpx_write_freemps(LPX *lp, const char *fname) |
---|
1464 | { /* write problem data in free MPS format */ |
---|
1465 | return glp_write_mps(lp, GLP_MPS_FILE, NULL, fname); |
---|
1466 | } |
---|
1467 | |
---|
1468 | LPX *lpx_read_cpxlp(const char *fname) |
---|
1469 | { /* read problem data in CPLEX LP format */ |
---|
1470 | LPX *lp; |
---|
1471 | lp = lpx_create_prob(); |
---|
1472 | if (glp_read_lp(lp, NULL, fname)) |
---|
1473 | lpx_delete_prob(lp), lp = NULL; |
---|
1474 | return lp; |
---|
1475 | } |
---|
1476 | |
---|
1477 | int lpx_write_cpxlp(LPX *lp, const char *fname) |
---|
1478 | { /* write problem data in CPLEX LP format */ |
---|
1479 | return glp_write_lp(lp, NULL, fname); |
---|
1480 | } |
---|
1481 | |
---|
1482 | LPX *lpx_read_model(const char *model, const char *data, const char |
---|
1483 | *output) |
---|
1484 | { /* read LP/MIP model written in GNU MathProg language */ |
---|
1485 | LPX *lp = NULL; |
---|
1486 | glp_tran *tran; |
---|
1487 | /* allocate the translator workspace */ |
---|
1488 | tran = glp_mpl_alloc_wksp(); |
---|
1489 | /* read model section and optional data section */ |
---|
1490 | if (glp_mpl_read_model(tran, model, data != NULL)) goto done; |
---|
1491 | /* read separate data section, if required */ |
---|
1492 | if (data != NULL) |
---|
1493 | if (glp_mpl_read_data(tran, data)) goto done; |
---|
1494 | /* generate the model */ |
---|
1495 | if (glp_mpl_generate(tran, output)) goto done; |
---|
1496 | /* build the problem instance from the model */ |
---|
1497 | lp = glp_create_prob(); |
---|
1498 | glp_mpl_build_prob(tran, lp); |
---|
1499 | done: /* free the translator workspace */ |
---|
1500 | glp_mpl_free_wksp(tran); |
---|
1501 | /* bring the problem object to the calling program */ |
---|
1502 | return lp; |
---|
1503 | } |
---|
1504 | |
---|
1505 | int lpx_print_prob(LPX *lp, const char *fname) |
---|
1506 | { /* write problem data in plain text format */ |
---|
1507 | return glp_write_lp(lp, NULL, fname); |
---|
1508 | } |
---|
1509 | |
---|
1510 | int lpx_print_sol(LPX *lp, const char *fname) |
---|
1511 | { /* write LP problem solution in printable format */ |
---|
1512 | return glp_print_sol(lp, fname); |
---|
1513 | } |
---|
1514 | |
---|
1515 | int lpx_print_sens_bnds(LPX *lp, const char *fname) |
---|
1516 | { /* write bounds sensitivity information */ |
---|
1517 | if (glp_get_status(lp) == GLP_OPT && !glp_bf_exists(lp)) |
---|
1518 | glp_factorize(lp); |
---|
1519 | return glp_print_ranges(lp, 0, NULL, 0, fname); |
---|
1520 | } |
---|
1521 | |
---|
1522 | int lpx_print_ips(LPX *lp, const char *fname) |
---|
1523 | { /* write interior point solution in printable format */ |
---|
1524 | return glp_print_ipt(lp, fname); |
---|
1525 | } |
---|
1526 | |
---|
1527 | int lpx_print_mip(LPX *lp, const char *fname) |
---|
1528 | { /* write MIP problem solution in printable format */ |
---|
1529 | return glp_print_mip(lp, fname); |
---|
1530 | } |
---|
1531 | |
---|
1532 | int lpx_is_b_avail(glp_prob *lp) |
---|
1533 | { /* check if LP basis is available */ |
---|
1534 | return glp_bf_exists(lp); |
---|
1535 | } |
---|
1536 | |
---|
1537 | int lpx_main(int argc, const char *argv[]) |
---|
1538 | { /* stand-alone LP/MIP solver */ |
---|
1539 | return glp_main(argc, argv); |
---|
1540 | } |
---|
1541 | |
---|
1542 | /* eof */ |
---|