COIN-OR::LEMON - Graph Library

source: glpk-cmake/src/glplpx01.c @ 2:4c8956a7bdf4

Last change on this file since 2:4c8956a7bdf4 was 1:c445c931472f, checked in by Alpar Juttner <alpar@…>, 14 years ago

Import glpk-4.45

  • Generated files and doc/notes are removed
File size: 47.9 KB
Line 
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
27struct 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
167LPX *lpx_create_prob(void)
168{     /* create problem object */
169      return glp_create_prob();
170}
171
172void 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
178void 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
184void 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
190int lpx_add_rows(LPX *lp, int nrs)
191{     /* add new rows to problem object */
192      return glp_add_rows(lp, nrs);
193}
194
195int lpx_add_cols(LPX *lp, int ncs)
196{     /* add new columns to problem object */
197      return glp_add_cols(lp, ncs);
198}
199
200void 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
206void 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
212void 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
218void 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
224void 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
230void 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
237void 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
244void 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
251void 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
257void 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
263void lpx_delete_prob(LPX *lp)
264{     /* delete problem object */
265      glp_delete_prob(lp);
266      return;
267}
268
269const char *lpx_get_prob_name(LPX *lp)
270{     /* retrieve problem name */
271      return glp_get_prob_name(lp);
272}
273
274const char *lpx_get_obj_name(LPX *lp)
275{     /* retrieve objective function name */
276      return glp_get_obj_name(lp);
277}
278
279int lpx_get_obj_dir(LPX *lp)
280{     /* retrieve optimization direction flag */
281      return glp_get_obj_dir(lp) - GLP_MIN + LPX_MIN;
282}
283
284int lpx_get_num_rows(LPX *lp)
285{     /* retrieve number of rows */
286      return glp_get_num_rows(lp);
287}
288
289int lpx_get_num_cols(LPX *lp)
290{     /* retrieve number of columns */
291      return glp_get_num_cols(lp);
292}
293
294const char *lpx_get_row_name(LPX *lp, int i)
295{     /* retrieve row name */
296      return glp_get_row_name(lp, i);
297}
298
299const char *lpx_get_col_name(LPX *lp, int j)
300{     /* retrieve column name */
301      return glp_get_col_name(lp, j);
302}
303
304int 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
309double 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
317double 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
325void 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
334int 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
339double 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
347double 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
355void 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
364double 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
369int lpx_get_num_nz(LPX *lp)
370{     /* retrieve number of constraint coefficients */
371      return glp_get_num_nz(lp);
372}
373
374int 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
379int 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
384void lpx_create_index(LPX *lp)
385{     /* create the name index */
386      glp_create_index(lp);
387      return;
388}
389
390int lpx_find_row(LPX *lp, const char *name)
391{     /* find row by its name */
392      return glp_find_row(lp, name);
393}
394
395int lpx_find_col(LPX *lp, const char *name)
396{     /* find column by its name */
397      return glp_find_col(lp, name);
398}
399
400void lpx_delete_index(LPX *lp)
401{     /* delete the name index */
402      glp_delete_index(lp);
403      return;
404}
405
406void 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
431void lpx_unscale_prob(LPX *lp)
432{     /* unscale problem data */
433      glp_unscale_prob(lp);
434      return;
435}
436
437void 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
443void 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
449void lpx_std_basis(LPX *lp)
450{     /* construct standard initial LP basis */
451      glp_std_basis(lp);
452      return;
453}
454
455void lpx_adv_basis(LPX *lp)
456{     /* construct advanced initial LP basis */
457      glp_adv_basis(lp, 0);
458      return;
459}
460
461void lpx_cpx_basis(LPX *lp)
462{     /* construct Bixby's initial LP basis */
463      glp_cpx_basis(lp);
464      return;
465}
466
467static 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
515int 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
539int 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
558int 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
573int 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
578int 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
583double lpx_get_obj_val(LPX *lp)
584{     /* retrieve objective value (basic solution) */
585      return glp_get_obj_val(lp);
586}
587
588int 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
593double 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
598double 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
603void 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
612int 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
617double 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
622double 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
627void 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
636int lpx_get_ray_info(LPX *lp)
637{     /* determine what causes primal unboundness */
638      return glp_get_unbnd_ray(lp);
639}
640
641void 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
714int 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
731int 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
736int 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
741int 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
746int 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
751int 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
760int 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
769int 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
785int 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
796double lpx_ipt_obj_val(LPX *lp)
797{     /* retrieve objective value (interior point) */
798      return glp_ipt_obj_val(lp);
799}
800
801double 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
806double 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
811double 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
816double 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
821void 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
829int lpx_get_class(LPX *lp)
830{     /* determine problem klass */
831      return glp_get_num_int(lp) == 0 ? LPX_LP : LPX_MIP;
832}
833
834void 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
840int 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
845int lpx_get_num_int(LPX *lp)
846{     /* retrieve number of integer columns */
847      return glp_get_num_int(lp);
848}
849
850int lpx_get_num_bin(LPX *lp)
851{     /* retrieve number of binary columns */
852      return glp_get_num_bin(lp);
853}
854
855static 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
923int lpx_integer(LPX *lp)
924{     /* easy-to-use driver to the branch-and-bound method */
925      return solve_mip(lp, GLP_OFF);
926}
927
928int lpx_intopt(LPX *lp)
929{     /* easy-to-use driver to the branch-and-bound method */
930      return solve_mip(lp, GLP_ON);
931}
932
933int 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
946double lpx_mip_obj_val(LPX *lp)
947{     /* retrieve objective value (MIP solution) */
948      return glp_mip_obj_val(lp);
949}
950
951double lpx_mip_row_val(LPX *lp, int i)
952{     /* retrieve row value (MIP solution) */
953      return glp_mip_row_val(lp, i);
954}
955
956double lpx_mip_col_val(LPX *lp, int j)
957{     /* retrieve column value (MIP solution) */
958      return glp_mip_col_val(lp, j);
959}
960
961void 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 */
997static 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 */
1039static 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 */
1050void 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
1058void 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
1211int 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
1286void 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
1369double 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
1418LPX *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
1426int 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
1431int 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
1443int 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
1455LPX *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
1463int 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
1468LPX *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
1477int 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
1482LPX *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);
1499done: /* free the translator workspace */
1500      glp_mpl_free_wksp(tran);
1501      /* bring the problem object to the calling program */
1502      return lp;
1503}
1504
1505int 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
1510int 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
1515int 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
1522int 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
1527int 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
1532int lpx_is_b_avail(glp_prob *lp)
1533{     /* check if LP basis is available */
1534      return glp_bf_exists(lp);
1535}
1536
1537int lpx_main(int argc, const char *argv[])
1538{     /* stand-alone LP/MIP solver */
1539      return glp_main(argc, argv);
1540}
1541
1542/* eof */
Note: See TracBrowser for help on using the repository browser.