1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/glplpx01.c Mon Dec 06 13:09:21 2010 +0100
1.3 @@ -0,0 +1,1542 @@
1.4 +/* glplpx01.c (obsolete API routines) */
1.5 +
1.6 +/***********************************************************************
1.7 +* This code is part of GLPK (GNU Linear Programming Kit).
1.8 +*
1.9 +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
1.10 +* 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
1.11 +* Moscow Aviation Institute, Moscow, Russia. All rights reserved.
1.12 +* E-mail: <mao@gnu.org>.
1.13 +*
1.14 +* GLPK is free software: you can redistribute it and/or modify it
1.15 +* under the terms of the GNU General Public License as published by
1.16 +* the Free Software Foundation, either version 3 of the License, or
1.17 +* (at your option) any later version.
1.18 +*
1.19 +* GLPK is distributed in the hope that it will be useful, but WITHOUT
1.20 +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1.21 +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1.22 +* License for more details.
1.23 +*
1.24 +* You should have received a copy of the GNU General Public License
1.25 +* along with GLPK. If not, see <http://www.gnu.org/licenses/>.
1.26 +***********************************************************************/
1.27 +
1.28 +#include "glpapi.h"
1.29 +
1.30 +struct LPXCPS
1.31 +{ /* control parameters and statistics */
1.32 + int msg_lev;
1.33 + /* level of messages output by the solver:
1.34 + 0 - no output
1.35 + 1 - error messages only
1.36 + 2 - normal output
1.37 + 3 - full output (includes informational messages) */
1.38 + int scale;
1.39 + /* scaling option:
1.40 + 0 - no scaling
1.41 + 1 - equilibration scaling
1.42 + 2 - geometric mean scaling
1.43 + 3 - geometric mean scaling, then equilibration scaling */
1.44 + int dual;
1.45 + /* dual simplex option:
1.46 + 0 - use primal simplex
1.47 + 1 - use dual simplex */
1.48 + int price;
1.49 + /* pricing option (for both primal and dual simplex):
1.50 + 0 - textbook pricing
1.51 + 1 - steepest edge pricing */
1.52 + double relax;
1.53 + /* relaxation parameter used in the ratio test; if it is zero,
1.54 + the textbook ratio test is used; if it is non-zero (should be
1.55 + positive), Harris' two-pass ratio test is used; in the latter
1.56 + case on the first pass basic variables (in the case of primal
1.57 + simplex) or reduced costs of non-basic variables (in the case
1.58 + of dual simplex) are allowed to slightly violate their bounds,
1.59 + but not more than (relax * tol_bnd) or (relax * tol_dj) (thus,
1.60 + relax is a percentage of tol_bnd or tol_dj) */
1.61 + double tol_bnd;
1.62 + /* relative tolerance used to check if the current basic solution
1.63 + is primal feasible */
1.64 + double tol_dj;
1.65 + /* absolute tolerance used to check if the current basic solution
1.66 + is dual feasible */
1.67 + double tol_piv;
1.68 + /* relative tolerance used to choose eligible pivotal elements of
1.69 + the simplex table in the ratio test */
1.70 + int round;
1.71 + /* solution rounding option:
1.72 + 0 - report all computed values and reduced costs "as is"
1.73 + 1 - if possible (allowed by the tolerances), replace computed
1.74 + values and reduced costs which are close to zero by exact
1.75 + zeros */
1.76 + double obj_ll;
1.77 + /* lower limit of the objective function; if on the phase II the
1.78 + objective function reaches this limit and continues decreasing,
1.79 + the solver stops the search */
1.80 + double obj_ul;
1.81 + /* upper limit of the objective function; if on the phase II the
1.82 + objective function reaches this limit and continues increasing,
1.83 + the solver stops the search */
1.84 + int it_lim;
1.85 + /* simplex iterations limit; if this value is positive, it is
1.86 + decreased by one each time when one simplex iteration has been
1.87 + performed, and reaching zero value signals the solver to stop
1.88 + the search; negative value means no iterations limit */
1.89 + double tm_lim;
1.90 + /* searching time limit, in seconds; if this value is positive,
1.91 + it is decreased each time when one simplex iteration has been
1.92 + performed by the amount of time spent for the iteration, and
1.93 + reaching zero value signals the solver to stop the search;
1.94 + negative value means no time limit */
1.95 + int out_frq;
1.96 + /* output frequency, in iterations; this parameter specifies how
1.97 + frequently the solver sends information about the solution to
1.98 + the standard output */
1.99 + double out_dly;
1.100 + /* output delay, in seconds; this parameter specifies how long
1.101 + the solver should delay sending information about the solution
1.102 + to the standard output; zero value means no delay */
1.103 + int branch; /* MIP */
1.104 + /* branching heuristic:
1.105 + 0 - branch on first variable
1.106 + 1 - branch on last variable
1.107 + 2 - branch using heuristic by Driebeck and Tomlin
1.108 + 3 - branch on most fractional variable */
1.109 + int btrack; /* MIP */
1.110 + /* backtracking heuristic:
1.111 + 0 - select most recent node (depth first search)
1.112 + 1 - select earliest node (breadth first search)
1.113 + 2 - select node using the best projection heuristic
1.114 + 3 - select node with best local bound */
1.115 + double tol_int; /* MIP */
1.116 + /* absolute tolerance used to check if the current basic solution
1.117 + is integer feasible */
1.118 + double tol_obj; /* MIP */
1.119 + /* relative tolerance used to check if the value of the objective
1.120 + function is not better than in the best known integer feasible
1.121 + solution */
1.122 + int mps_info; /* lpx_write_mps */
1.123 + /* if this flag is set, the routine lpx_write_mps outputs several
1.124 + comment cards that contains some information about the problem;
1.125 + otherwise the routine outputs no comment cards */
1.126 + int mps_obj; /* lpx_write_mps */
1.127 + /* this parameter tells the routine lpx_write_mps how to output
1.128 + the objective function row:
1.129 + 0 - never output objective function row
1.130 + 1 - always output objective function row
1.131 + 2 - output objective function row if and only if the problem
1.132 + has no free rows */
1.133 + int mps_orig; /* lpx_write_mps */
1.134 + /* if this flag is set, the routine lpx_write_mps uses original
1.135 + row and column symbolic names; otherwise the routine generates
1.136 + plain names using ordinal numbers of rows and columns */
1.137 + int mps_wide; /* lpx_write_mps */
1.138 + /* if this flag is set, the routine lpx_write_mps uses all data
1.139 + fields; otherwise the routine keeps fields 5 and 6 empty */
1.140 + int mps_free; /* lpx_write_mps */
1.141 + /* if this flag is set, the routine lpx_write_mps omits column
1.142 + and vector names everytime if possible (free style); otherwise
1.143 + the routine never omits these names (pedantic style) */
1.144 + int mps_skip; /* lpx_write_mps */
1.145 + /* if this flag is set, the routine lpx_write_mps skips empty
1.146 + columns (i.e. which has no constraint coefficients); otherwise
1.147 + the routine outputs all columns */
1.148 + int lpt_orig; /* lpx_write_lpt */
1.149 + /* if this flag is set, the routine lpx_write_lpt uses original
1.150 + row and column symbolic names; otherwise the routine generates
1.151 + plain names using ordinal numbers of rows and columns */
1.152 + int presol; /* lpx_simplex */
1.153 + /* LP presolver option:
1.154 + 0 - do not use LP presolver
1.155 + 1 - use LP presolver */
1.156 + int binarize; /* lpx_intopt */
1.157 + /* if this flag is set, the routine lpx_intopt replaces integer
1.158 + columns by binary ones */
1.159 + int use_cuts; /* lpx_intopt */
1.160 + /* if this flag is set, the routine lpx_intopt tries generating
1.161 + cutting planes:
1.162 + LPX_C_COVER - mixed cover cuts
1.163 + LPX_C_CLIQUE - clique cuts
1.164 + LPX_C_GOMORY - Gomory's mixed integer cuts
1.165 + LPX_C_ALL - all cuts */
1.166 + double mip_gap; /* MIP */
1.167 + /* relative MIP gap tolerance */
1.168 +};
1.169 +
1.170 +LPX *lpx_create_prob(void)
1.171 +{ /* create problem object */
1.172 + return glp_create_prob();
1.173 +}
1.174 +
1.175 +void lpx_set_prob_name(LPX *lp, const char *name)
1.176 +{ /* assign (change) problem name */
1.177 + glp_set_prob_name(lp, name);
1.178 + return;
1.179 +}
1.180 +
1.181 +void lpx_set_obj_name(LPX *lp, const char *name)
1.182 +{ /* assign (change) objective function name */
1.183 + glp_set_obj_name(lp, name);
1.184 + return;
1.185 +}
1.186 +
1.187 +void lpx_set_obj_dir(LPX *lp, int dir)
1.188 +{ /* set (change) optimization direction flag */
1.189 + glp_set_obj_dir(lp, dir - LPX_MIN + GLP_MIN);
1.190 + return;
1.191 +}
1.192 +
1.193 +int lpx_add_rows(LPX *lp, int nrs)
1.194 +{ /* add new rows to problem object */
1.195 + return glp_add_rows(lp, nrs);
1.196 +}
1.197 +
1.198 +int lpx_add_cols(LPX *lp, int ncs)
1.199 +{ /* add new columns to problem object */
1.200 + return glp_add_cols(lp, ncs);
1.201 +}
1.202 +
1.203 +void lpx_set_row_name(LPX *lp, int i, const char *name)
1.204 +{ /* assign (change) row name */
1.205 + glp_set_row_name(lp, i, name);
1.206 + return;
1.207 +}
1.208 +
1.209 +void lpx_set_col_name(LPX *lp, int j, const char *name)
1.210 +{ /* assign (change) column name */
1.211 + glp_set_col_name(lp, j, name);
1.212 + return;
1.213 +}
1.214 +
1.215 +void lpx_set_row_bnds(LPX *lp, int i, int type, double lb, double ub)
1.216 +{ /* set (change) row bounds */
1.217 + glp_set_row_bnds(lp, i, type - LPX_FR + GLP_FR, lb, ub);
1.218 + return;
1.219 +}
1.220 +
1.221 +void lpx_set_col_bnds(LPX *lp, int j, int type, double lb, double ub)
1.222 +{ /* set (change) column bounds */
1.223 + glp_set_col_bnds(lp, j, type - LPX_FR + GLP_FR, lb, ub);
1.224 + return;
1.225 +}
1.226 +
1.227 +void lpx_set_obj_coef(glp_prob *lp, int j, double coef)
1.228 +{ /* set (change) obj. coefficient or constant term */
1.229 + glp_set_obj_coef(lp, j, coef);
1.230 + return;
1.231 +}
1.232 +
1.233 +void lpx_set_mat_row(LPX *lp, int i, int len, const int ind[],
1.234 + const double val[])
1.235 +{ /* set (replace) row of the constraint matrix */
1.236 + glp_set_mat_row(lp, i, len, ind, val);
1.237 + return;
1.238 +}
1.239 +
1.240 +void lpx_set_mat_col(LPX *lp, int j, int len, const int ind[],
1.241 + const double val[])
1.242 +{ /* set (replace) column of the constraint matrix */
1.243 + glp_set_mat_col(lp, j, len, ind, val);
1.244 + return;
1.245 +}
1.246 +
1.247 +void lpx_load_matrix(LPX *lp, int ne, const int ia[], const int ja[],
1.248 + const double ar[])
1.249 +{ /* load (replace) the whole constraint matrix */
1.250 + glp_load_matrix(lp, ne, ia, ja, ar);
1.251 + return;
1.252 +}
1.253 +
1.254 +void lpx_del_rows(LPX *lp, int nrs, const int num[])
1.255 +{ /* delete specified rows from problem object */
1.256 + glp_del_rows(lp, nrs, num);
1.257 + return;
1.258 +}
1.259 +
1.260 +void lpx_del_cols(LPX *lp, int ncs, const int num[])
1.261 +{ /* delete specified columns from problem object */
1.262 + glp_del_cols(lp, ncs, num);
1.263 + return;
1.264 +}
1.265 +
1.266 +void lpx_delete_prob(LPX *lp)
1.267 +{ /* delete problem object */
1.268 + glp_delete_prob(lp);
1.269 + return;
1.270 +}
1.271 +
1.272 +const char *lpx_get_prob_name(LPX *lp)
1.273 +{ /* retrieve problem name */
1.274 + return glp_get_prob_name(lp);
1.275 +}
1.276 +
1.277 +const char *lpx_get_obj_name(LPX *lp)
1.278 +{ /* retrieve objective function name */
1.279 + return glp_get_obj_name(lp);
1.280 +}
1.281 +
1.282 +int lpx_get_obj_dir(LPX *lp)
1.283 +{ /* retrieve optimization direction flag */
1.284 + return glp_get_obj_dir(lp) - GLP_MIN + LPX_MIN;
1.285 +}
1.286 +
1.287 +int lpx_get_num_rows(LPX *lp)
1.288 +{ /* retrieve number of rows */
1.289 + return glp_get_num_rows(lp);
1.290 +}
1.291 +
1.292 +int lpx_get_num_cols(LPX *lp)
1.293 +{ /* retrieve number of columns */
1.294 + return glp_get_num_cols(lp);
1.295 +}
1.296 +
1.297 +const char *lpx_get_row_name(LPX *lp, int i)
1.298 +{ /* retrieve row name */
1.299 + return glp_get_row_name(lp, i);
1.300 +}
1.301 +
1.302 +const char *lpx_get_col_name(LPX *lp, int j)
1.303 +{ /* retrieve column name */
1.304 + return glp_get_col_name(lp, j);
1.305 +}
1.306 +
1.307 +int lpx_get_row_type(LPX *lp, int i)
1.308 +{ /* retrieve row type */
1.309 + return glp_get_row_type(lp, i) - GLP_FR + LPX_FR;
1.310 +}
1.311 +
1.312 +double lpx_get_row_lb(glp_prob *lp, int i)
1.313 +{ /* retrieve row lower bound */
1.314 + double lb;
1.315 + lb = glp_get_row_lb(lp, i);
1.316 + if (lb == -DBL_MAX) lb = 0.0;
1.317 + return lb;
1.318 +}
1.319 +
1.320 +double lpx_get_row_ub(glp_prob *lp, int i)
1.321 +{ /* retrieve row upper bound */
1.322 + double ub;
1.323 + ub = glp_get_row_ub(lp, i);
1.324 + if (ub == +DBL_MAX) ub = 0.0;
1.325 + return ub;
1.326 +}
1.327 +
1.328 +void lpx_get_row_bnds(glp_prob *lp, int i, int *typx, double *lb,
1.329 + double *ub)
1.330 +{ /* retrieve row bounds */
1.331 + if (typx != NULL) *typx = lpx_get_row_type(lp, i);
1.332 + if (lb != NULL) *lb = lpx_get_row_lb(lp, i);
1.333 + if (ub != NULL) *ub = lpx_get_row_ub(lp, i);
1.334 + return;
1.335 +}
1.336 +
1.337 +int lpx_get_col_type(LPX *lp, int j)
1.338 +{ /* retrieve column type */
1.339 + return glp_get_col_type(lp, j) - GLP_FR + LPX_FR;
1.340 +}
1.341 +
1.342 +double lpx_get_col_lb(glp_prob *lp, int j)
1.343 +{ /* retrieve column lower bound */
1.344 + double lb;
1.345 + lb = glp_get_col_lb(lp, j);
1.346 + if (lb == -DBL_MAX) lb = 0.0;
1.347 + return lb;
1.348 +}
1.349 +
1.350 +double lpx_get_col_ub(glp_prob *lp, int j)
1.351 +{ /* retrieve column upper bound */
1.352 + double ub;
1.353 + ub = glp_get_col_ub(lp, j);
1.354 + if (ub == +DBL_MAX) ub = 0.0;
1.355 + return ub;
1.356 +}
1.357 +
1.358 +void lpx_get_col_bnds(glp_prob *lp, int j, int *typx, double *lb,
1.359 + double *ub)
1.360 +{ /* retrieve column bounds */
1.361 + if (typx != NULL) *typx = lpx_get_col_type(lp, j);
1.362 + if (lb != NULL) *lb = lpx_get_col_lb(lp, j);
1.363 + if (ub != NULL) *ub = lpx_get_col_ub(lp, j);
1.364 + return;
1.365 +}
1.366 +
1.367 +double lpx_get_obj_coef(LPX *lp, int j)
1.368 +{ /* retrieve obj. coefficient or constant term */
1.369 + return glp_get_obj_coef(lp, j);
1.370 +}
1.371 +
1.372 +int lpx_get_num_nz(LPX *lp)
1.373 +{ /* retrieve number of constraint coefficients */
1.374 + return glp_get_num_nz(lp);
1.375 +}
1.376 +
1.377 +int lpx_get_mat_row(LPX *lp, int i, int ind[], double val[])
1.378 +{ /* retrieve row of the constraint matrix */
1.379 + return glp_get_mat_row(lp, i, ind, val);
1.380 +}
1.381 +
1.382 +int lpx_get_mat_col(LPX *lp, int j, int ind[], double val[])
1.383 +{ /* retrieve column of the constraint matrix */
1.384 + return glp_get_mat_col(lp, j, ind, val);
1.385 +}
1.386 +
1.387 +void lpx_create_index(LPX *lp)
1.388 +{ /* create the name index */
1.389 + glp_create_index(lp);
1.390 + return;
1.391 +}
1.392 +
1.393 +int lpx_find_row(LPX *lp, const char *name)
1.394 +{ /* find row by its name */
1.395 + return glp_find_row(lp, name);
1.396 +}
1.397 +
1.398 +int lpx_find_col(LPX *lp, const char *name)
1.399 +{ /* find column by its name */
1.400 + return glp_find_col(lp, name);
1.401 +}
1.402 +
1.403 +void lpx_delete_index(LPX *lp)
1.404 +{ /* delete the name index */
1.405 + glp_delete_index(lp);
1.406 + return;
1.407 +}
1.408 +
1.409 +void lpx_scale_prob(LPX *lp)
1.410 +{ /* scale problem data */
1.411 + switch (lpx_get_int_parm(lp, LPX_K_SCALE))
1.412 + { case 0:
1.413 + /* no scaling */
1.414 + glp_unscale_prob(lp);
1.415 + break;
1.416 + case 1:
1.417 + /* equilibration scaling */
1.418 + glp_scale_prob(lp, GLP_SF_EQ);
1.419 + break;
1.420 + case 2:
1.421 + /* geometric mean scaling */
1.422 + glp_scale_prob(lp, GLP_SF_GM);
1.423 + break;
1.424 + case 3:
1.425 + /* geometric mean scaling, then equilibration scaling */
1.426 + glp_scale_prob(lp, GLP_SF_GM | GLP_SF_EQ);
1.427 + break;
1.428 + default:
1.429 + xassert(lp != lp);
1.430 + }
1.431 + return;
1.432 +}
1.433 +
1.434 +void lpx_unscale_prob(LPX *lp)
1.435 +{ /* unscale problem data */
1.436 + glp_unscale_prob(lp);
1.437 + return;
1.438 +}
1.439 +
1.440 +void lpx_set_row_stat(LPX *lp, int i, int stat)
1.441 +{ /* set (change) row status */
1.442 + glp_set_row_stat(lp, i, stat - LPX_BS + GLP_BS);
1.443 + return;
1.444 +}
1.445 +
1.446 +void lpx_set_col_stat(LPX *lp, int j, int stat)
1.447 +{ /* set (change) column status */
1.448 + glp_set_col_stat(lp, j, stat - LPX_BS + GLP_BS);
1.449 + return;
1.450 +}
1.451 +
1.452 +void lpx_std_basis(LPX *lp)
1.453 +{ /* construct standard initial LP basis */
1.454 + glp_std_basis(lp);
1.455 + return;
1.456 +}
1.457 +
1.458 +void lpx_adv_basis(LPX *lp)
1.459 +{ /* construct advanced initial LP basis */
1.460 + glp_adv_basis(lp, 0);
1.461 + return;
1.462 +}
1.463 +
1.464 +void lpx_cpx_basis(LPX *lp)
1.465 +{ /* construct Bixby's initial LP basis */
1.466 + glp_cpx_basis(lp);
1.467 + return;
1.468 +}
1.469 +
1.470 +static void fill_smcp(LPX *lp, glp_smcp *parm)
1.471 +{ glp_init_smcp(parm);
1.472 + switch (lpx_get_int_parm(lp, LPX_K_MSGLEV))
1.473 + { case 0: parm->msg_lev = GLP_MSG_OFF; break;
1.474 + case 1: parm->msg_lev = GLP_MSG_ERR; break;
1.475 + case 2: parm->msg_lev = GLP_MSG_ON; break;
1.476 + case 3: parm->msg_lev = GLP_MSG_ALL; break;
1.477 + default: xassert(lp != lp);
1.478 + }
1.479 + switch (lpx_get_int_parm(lp, LPX_K_DUAL))
1.480 + { case 0: parm->meth = GLP_PRIMAL; break;
1.481 + case 1: parm->meth = GLP_DUAL; break;
1.482 + default: xassert(lp != lp);
1.483 + }
1.484 + switch (lpx_get_int_parm(lp, LPX_K_PRICE))
1.485 + { case 0: parm->pricing = GLP_PT_STD; break;
1.486 + case 1: parm->pricing = GLP_PT_PSE; break;
1.487 + default: xassert(lp != lp);
1.488 + }
1.489 + if (lpx_get_real_parm(lp, LPX_K_RELAX) == 0.0)
1.490 + parm->r_test = GLP_RT_STD;
1.491 + else
1.492 + parm->r_test = GLP_RT_HAR;
1.493 + parm->tol_bnd = lpx_get_real_parm(lp, LPX_K_TOLBND);
1.494 + parm->tol_dj = lpx_get_real_parm(lp, LPX_K_TOLDJ);
1.495 + parm->tol_piv = lpx_get_real_parm(lp, LPX_K_TOLPIV);
1.496 + parm->obj_ll = lpx_get_real_parm(lp, LPX_K_OBJLL);
1.497 + parm->obj_ul = lpx_get_real_parm(lp, LPX_K_OBJUL);
1.498 + if (lpx_get_int_parm(lp, LPX_K_ITLIM) < 0)
1.499 + parm->it_lim = INT_MAX;
1.500 + else
1.501 + parm->it_lim = lpx_get_int_parm(lp, LPX_K_ITLIM);
1.502 + if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0)
1.503 + parm->tm_lim = INT_MAX;
1.504 + else
1.505 + parm->tm_lim =
1.506 + (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM));
1.507 + parm->out_frq = lpx_get_int_parm(lp, LPX_K_OUTFRQ);
1.508 + parm->out_dly =
1.509 + (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_OUTDLY));
1.510 + switch (lpx_get_int_parm(lp, LPX_K_PRESOL))
1.511 + { case 0: parm->presolve = GLP_OFF; break;
1.512 + case 1: parm->presolve = GLP_ON; break;
1.513 + default: xassert(lp != lp);
1.514 + }
1.515 + return;
1.516 +}
1.517 +
1.518 +int lpx_simplex(LPX *lp)
1.519 +{ /* easy-to-use driver to the simplex method */
1.520 + glp_smcp parm;
1.521 + int ret;
1.522 + fill_smcp(lp, &parm);
1.523 + ret = glp_simplex(lp, &parm);
1.524 + switch (ret)
1.525 + { case 0: ret = LPX_E_OK; break;
1.526 + case GLP_EBADB:
1.527 + case GLP_ESING:
1.528 + case GLP_ECOND:
1.529 + case GLP_EBOUND: ret = LPX_E_FAULT; break;
1.530 + case GLP_EFAIL: ret = LPX_E_SING; break;
1.531 + case GLP_EOBJLL: ret = LPX_E_OBJLL; break;
1.532 + case GLP_EOBJUL: ret = LPX_E_OBJUL; break;
1.533 + case GLP_EITLIM: ret = LPX_E_ITLIM; break;
1.534 + case GLP_ETMLIM: ret = LPX_E_TMLIM; break;
1.535 + case GLP_ENOPFS: ret = LPX_E_NOPFS; break;
1.536 + case GLP_ENODFS: ret = LPX_E_NODFS; break;
1.537 + default: xassert(ret != ret);
1.538 + }
1.539 + return ret;
1.540 +}
1.541 +
1.542 +int lpx_exact(LPX *lp)
1.543 +{ /* easy-to-use driver to the exact simplex method */
1.544 + glp_smcp parm;
1.545 + int ret;
1.546 + fill_smcp(lp, &parm);
1.547 + ret = glp_exact(lp, &parm);
1.548 + switch (ret)
1.549 + { case 0: ret = LPX_E_OK; break;
1.550 + case GLP_EBADB:
1.551 + case GLP_ESING:
1.552 + case GLP_EBOUND:
1.553 + case GLP_EFAIL: ret = LPX_E_FAULT; break;
1.554 + case GLP_EITLIM: ret = LPX_E_ITLIM; break;
1.555 + case GLP_ETMLIM: ret = LPX_E_TMLIM; break;
1.556 + default: xassert(ret != ret);
1.557 + }
1.558 + return ret;
1.559 +}
1.560 +
1.561 +int lpx_get_status(glp_prob *lp)
1.562 +{ /* retrieve generic status of basic solution */
1.563 + int status;
1.564 + switch (glp_get_status(lp))
1.565 + { case GLP_OPT: status = LPX_OPT; break;
1.566 + case GLP_FEAS: status = LPX_FEAS; break;
1.567 + case GLP_INFEAS: status = LPX_INFEAS; break;
1.568 + case GLP_NOFEAS: status = LPX_NOFEAS; break;
1.569 + case GLP_UNBND: status = LPX_UNBND; break;
1.570 + case GLP_UNDEF: status = LPX_UNDEF; break;
1.571 + default: xassert(lp != lp);
1.572 + }
1.573 + return status;
1.574 +}
1.575 +
1.576 +int lpx_get_prim_stat(glp_prob *lp)
1.577 +{ /* retrieve status of primal basic solution */
1.578 + return glp_get_prim_stat(lp) - GLP_UNDEF + LPX_P_UNDEF;
1.579 +}
1.580 +
1.581 +int lpx_get_dual_stat(glp_prob *lp)
1.582 +{ /* retrieve status of dual basic solution */
1.583 + return glp_get_dual_stat(lp) - GLP_UNDEF + LPX_D_UNDEF;
1.584 +}
1.585 +
1.586 +double lpx_get_obj_val(LPX *lp)
1.587 +{ /* retrieve objective value (basic solution) */
1.588 + return glp_get_obj_val(lp);
1.589 +}
1.590 +
1.591 +int lpx_get_row_stat(LPX *lp, int i)
1.592 +{ /* retrieve row status (basic solution) */
1.593 + return glp_get_row_stat(lp, i) - GLP_BS + LPX_BS;
1.594 +}
1.595 +
1.596 +double lpx_get_row_prim(LPX *lp, int i)
1.597 +{ /* retrieve row primal value (basic solution) */
1.598 + return glp_get_row_prim(lp, i);
1.599 +}
1.600 +
1.601 +double lpx_get_row_dual(LPX *lp, int i)
1.602 +{ /* retrieve row dual value (basic solution) */
1.603 + return glp_get_row_dual(lp, i);
1.604 +}
1.605 +
1.606 +void lpx_get_row_info(glp_prob *lp, int i, int *tagx, double *vx,
1.607 + double *dx)
1.608 +{ /* obtain row solution information */
1.609 + if (tagx != NULL) *tagx = lpx_get_row_stat(lp, i);
1.610 + if (vx != NULL) *vx = lpx_get_row_prim(lp, i);
1.611 + if (dx != NULL) *dx = lpx_get_row_dual(lp, i);
1.612 + return;
1.613 +}
1.614 +
1.615 +int lpx_get_col_stat(LPX *lp, int j)
1.616 +{ /* retrieve column status (basic solution) */
1.617 + return glp_get_col_stat(lp, j) - GLP_BS + LPX_BS;
1.618 +}
1.619 +
1.620 +double lpx_get_col_prim(LPX *lp, int j)
1.621 +{ /* retrieve column primal value (basic solution) */
1.622 + return glp_get_col_prim(lp, j);
1.623 +}
1.624 +
1.625 +double lpx_get_col_dual(glp_prob *lp, int j)
1.626 +{ /* retrieve column dual value (basic solution) */
1.627 + return glp_get_col_dual(lp, j);
1.628 +}
1.629 +
1.630 +void lpx_get_col_info(glp_prob *lp, int j, int *tagx, double *vx,
1.631 + double *dx)
1.632 +{ /* obtain column solution information */
1.633 + if (tagx != NULL) *tagx = lpx_get_col_stat(lp, j);
1.634 + if (vx != NULL) *vx = lpx_get_col_prim(lp, j);
1.635 + if (dx != NULL) *dx = lpx_get_col_dual(lp, j);
1.636 + return;
1.637 +}
1.638 +
1.639 +int lpx_get_ray_info(LPX *lp)
1.640 +{ /* determine what causes primal unboundness */
1.641 + return glp_get_unbnd_ray(lp);
1.642 +}
1.643 +
1.644 +void lpx_check_kkt(LPX *lp, int scaled, LPXKKT *kkt)
1.645 +{ /* check Karush-Kuhn-Tucker conditions */
1.646 + int ae_ind, re_ind;
1.647 + double ae_max, re_max;
1.648 + xassert(scaled == scaled);
1.649 + _glp_check_kkt(lp, GLP_SOL, GLP_KKT_PE, &ae_max, &ae_ind, &re_max,
1.650 + &re_ind);
1.651 + kkt->pe_ae_max = ae_max;
1.652 + kkt->pe_ae_row = ae_ind;
1.653 + kkt->pe_re_max = re_max;
1.654 + kkt->pe_re_row = re_ind;
1.655 + if (re_max <= 1e-9)
1.656 + kkt->pe_quality = 'H';
1.657 + else if (re_max <= 1e-6)
1.658 + kkt->pe_quality = 'M';
1.659 + else if (re_max <= 1e-3)
1.660 + kkt->pe_quality = 'L';
1.661 + else
1.662 + kkt->pe_quality = '?';
1.663 + _glp_check_kkt(lp, GLP_SOL, GLP_KKT_PB, &ae_max, &ae_ind, &re_max,
1.664 + &re_ind);
1.665 + kkt->pb_ae_max = ae_max;
1.666 + kkt->pb_ae_ind = ae_ind;
1.667 + kkt->pb_re_max = re_max;
1.668 + kkt->pb_re_ind = re_ind;
1.669 + if (re_max <= 1e-9)
1.670 + kkt->pb_quality = 'H';
1.671 + else if (re_max <= 1e-6)
1.672 + kkt->pb_quality = 'M';
1.673 + else if (re_max <= 1e-3)
1.674 + kkt->pb_quality = 'L';
1.675 + else
1.676 + kkt->pb_quality = '?';
1.677 + _glp_check_kkt(lp, GLP_SOL, GLP_KKT_DE, &ae_max, &ae_ind, &re_max,
1.678 + &re_ind);
1.679 + kkt->de_ae_max = ae_max;
1.680 + if (ae_ind == 0)
1.681 + kkt->de_ae_col = 0;
1.682 + else
1.683 + kkt->de_ae_col = ae_ind - lp->m;
1.684 + kkt->de_re_max = re_max;
1.685 + if (re_ind == 0)
1.686 + kkt->de_re_col = 0;
1.687 + else
1.688 + kkt->de_re_col = ae_ind - lp->m;
1.689 + if (re_max <= 1e-9)
1.690 + kkt->de_quality = 'H';
1.691 + else if (re_max <= 1e-6)
1.692 + kkt->de_quality = 'M';
1.693 + else if (re_max <= 1e-3)
1.694 + kkt->de_quality = 'L';
1.695 + else
1.696 + kkt->de_quality = '?';
1.697 + _glp_check_kkt(lp, GLP_SOL, GLP_KKT_DB, &ae_max, &ae_ind, &re_max,
1.698 + &re_ind);
1.699 + kkt->db_ae_max = ae_max;
1.700 + kkt->db_ae_ind = ae_ind;
1.701 + kkt->db_re_max = re_max;
1.702 + kkt->db_re_ind = re_ind;
1.703 + if (re_max <= 1e-9)
1.704 + kkt->db_quality = 'H';
1.705 + else if (re_max <= 1e-6)
1.706 + kkt->db_quality = 'M';
1.707 + else if (re_max <= 1e-3)
1.708 + kkt->db_quality = 'L';
1.709 + else
1.710 + kkt->db_quality = '?';
1.711 + kkt->cs_ae_max = 0.0, kkt->cs_ae_ind = 0;
1.712 + kkt->cs_re_max = 0.0, kkt->cs_re_ind = 0;
1.713 + kkt->cs_quality = 'H';
1.714 + return;
1.715 +}
1.716 +
1.717 +int lpx_warm_up(LPX *lp)
1.718 +{ /* "warm up" LP basis */
1.719 + int ret;
1.720 + ret = glp_warm_up(lp);
1.721 + if (ret == 0)
1.722 + ret = LPX_E_OK;
1.723 + else if (ret == GLP_EBADB)
1.724 + ret = LPX_E_BADB;
1.725 + else if (ret == GLP_ESING)
1.726 + ret = LPX_E_SING;
1.727 + else if (ret == GLP_ECOND)
1.728 + ret = LPX_E_SING;
1.729 + else
1.730 + xassert(ret != ret);
1.731 + return ret;
1.732 +}
1.733 +
1.734 +int lpx_eval_tab_row(LPX *lp, int k, int ind[], double val[])
1.735 +{ /* compute row of the simplex tableau */
1.736 + return glp_eval_tab_row(lp, k, ind, val);
1.737 +}
1.738 +
1.739 +int lpx_eval_tab_col(LPX *lp, int k, int ind[], double val[])
1.740 +{ /* compute column of the simplex tableau */
1.741 + return glp_eval_tab_col(lp, k, ind, val);
1.742 +}
1.743 +
1.744 +int lpx_transform_row(LPX *lp, int len, int ind[], double val[])
1.745 +{ /* transform explicitly specified row */
1.746 + return glp_transform_row(lp, len, ind, val);
1.747 +}
1.748 +
1.749 +int lpx_transform_col(LPX *lp, int len, int ind[], double val[])
1.750 +{ /* transform explicitly specified column */
1.751 + return glp_transform_col(lp, len, ind, val);
1.752 +}
1.753 +
1.754 +int lpx_prim_ratio_test(LPX *lp, int len, const int ind[],
1.755 + const double val[], int how, double tol)
1.756 +{ /* perform primal ratio test */
1.757 + int piv;
1.758 + piv = glp_prim_rtest(lp, len, ind, val, how, tol);
1.759 + xassert(0 <= piv && piv <= len);
1.760 + return piv == 0 ? 0 : ind[piv];
1.761 +}
1.762 +
1.763 +int lpx_dual_ratio_test(LPX *lp, int len, const int ind[],
1.764 + const double val[], int how, double tol)
1.765 +{ /* perform dual ratio test */
1.766 + int piv;
1.767 + piv = glp_dual_rtest(lp, len, ind, val, how, tol);
1.768 + xassert(0 <= piv && piv <= len);
1.769 + return piv == 0 ? 0 : ind[piv];
1.770 +}
1.771 +
1.772 +int lpx_interior(LPX *lp)
1.773 +{ /* easy-to-use driver to the interior-point method */
1.774 + int ret;
1.775 + ret = glp_interior(lp, NULL);
1.776 + switch (ret)
1.777 + { case 0: ret = LPX_E_OK; break;
1.778 + case GLP_EFAIL: ret = LPX_E_FAULT; break;
1.779 + case GLP_ENOFEAS: ret = LPX_E_NOFEAS; break;
1.780 + case GLP_ENOCVG: ret = LPX_E_NOCONV; break;
1.781 + case GLP_EITLIM: ret = LPX_E_ITLIM; break;
1.782 + case GLP_EINSTAB: ret = LPX_E_INSTAB; break;
1.783 + default: xassert(ret != ret);
1.784 + }
1.785 + return ret;
1.786 +}
1.787 +
1.788 +int lpx_ipt_status(glp_prob *lp)
1.789 +{ /* retrieve status of interior-point solution */
1.790 + int status;
1.791 + switch (glp_ipt_status(lp))
1.792 + { case GLP_UNDEF: status = LPX_T_UNDEF; break;
1.793 + case GLP_OPT: status = LPX_T_OPT; break;
1.794 + default: xassert(lp != lp);
1.795 + }
1.796 + return status;
1.797 +}
1.798 +
1.799 +double lpx_ipt_obj_val(LPX *lp)
1.800 +{ /* retrieve objective value (interior point) */
1.801 + return glp_ipt_obj_val(lp);
1.802 +}
1.803 +
1.804 +double lpx_ipt_row_prim(LPX *lp, int i)
1.805 +{ /* retrieve row primal value (interior point) */
1.806 + return glp_ipt_row_prim(lp, i);
1.807 +}
1.808 +
1.809 +double lpx_ipt_row_dual(LPX *lp, int i)
1.810 +{ /* retrieve row dual value (interior point) */
1.811 + return glp_ipt_row_dual(lp, i);
1.812 +}
1.813 +
1.814 +double lpx_ipt_col_prim(LPX *lp, int j)
1.815 +{ /* retrieve column primal value (interior point) */
1.816 + return glp_ipt_col_prim(lp, j);
1.817 +}
1.818 +
1.819 +double lpx_ipt_col_dual(LPX *lp, int j)
1.820 +{ /* retrieve column dual value (interior point) */
1.821 + return glp_ipt_col_dual(lp, j);
1.822 +}
1.823 +
1.824 +void lpx_set_class(LPX *lp, int klass)
1.825 +{ /* set problem class */
1.826 + xassert(lp == lp);
1.827 + if (!(klass == LPX_LP || klass == LPX_MIP))
1.828 + xerror("lpx_set_class: invalid problem class\n");
1.829 + return;
1.830 +}
1.831 +
1.832 +int lpx_get_class(LPX *lp)
1.833 +{ /* determine problem klass */
1.834 + return glp_get_num_int(lp) == 0 ? LPX_LP : LPX_MIP;
1.835 +}
1.836 +
1.837 +void lpx_set_col_kind(LPX *lp, int j, int kind)
1.838 +{ /* set (change) column kind */
1.839 + glp_set_col_kind(lp, j, kind - LPX_CV + GLP_CV);
1.840 + return;
1.841 +}
1.842 +
1.843 +int lpx_get_col_kind(LPX *lp, int j)
1.844 +{ /* retrieve column kind */
1.845 + return glp_get_col_kind(lp, j) == GLP_CV ? LPX_CV : LPX_IV;
1.846 +}
1.847 +
1.848 +int lpx_get_num_int(LPX *lp)
1.849 +{ /* retrieve number of integer columns */
1.850 + return glp_get_num_int(lp);
1.851 +}
1.852 +
1.853 +int lpx_get_num_bin(LPX *lp)
1.854 +{ /* retrieve number of binary columns */
1.855 + return glp_get_num_bin(lp);
1.856 +}
1.857 +
1.858 +static int solve_mip(LPX *lp, int presolve)
1.859 +{ glp_iocp parm;
1.860 + int ret;
1.861 + glp_init_iocp(&parm);
1.862 + switch (lpx_get_int_parm(lp, LPX_K_MSGLEV))
1.863 + { case 0: parm.msg_lev = GLP_MSG_OFF; break;
1.864 + case 1: parm.msg_lev = GLP_MSG_ERR; break;
1.865 + case 2: parm.msg_lev = GLP_MSG_ON; break;
1.866 + case 3: parm.msg_lev = GLP_MSG_ALL; break;
1.867 + default: xassert(lp != lp);
1.868 + }
1.869 + switch (lpx_get_int_parm(lp, LPX_K_BRANCH))
1.870 + { case 0: parm.br_tech = GLP_BR_FFV; break;
1.871 + case 1: parm.br_tech = GLP_BR_LFV; break;
1.872 + case 2: parm.br_tech = GLP_BR_DTH; break;
1.873 + case 3: parm.br_tech = GLP_BR_MFV; break;
1.874 + default: xassert(lp != lp);
1.875 + }
1.876 + switch (lpx_get_int_parm(lp, LPX_K_BTRACK))
1.877 + { case 0: parm.bt_tech = GLP_BT_DFS; break;
1.878 + case 1: parm.bt_tech = GLP_BT_BFS; break;
1.879 + case 2: parm.bt_tech = GLP_BT_BPH; break;
1.880 + case 3: parm.bt_tech = GLP_BT_BLB; break;
1.881 + default: xassert(lp != lp);
1.882 + }
1.883 + parm.tol_int = lpx_get_real_parm(lp, LPX_K_TOLINT);
1.884 + parm.tol_obj = lpx_get_real_parm(lp, LPX_K_TOLOBJ);
1.885 + if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0 ||
1.886 + lpx_get_real_parm(lp, LPX_K_TMLIM) > 1e6)
1.887 + parm.tm_lim = INT_MAX;
1.888 + else
1.889 + parm.tm_lim =
1.890 + (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM));
1.891 + parm.mip_gap = lpx_get_real_parm(lp, LPX_K_MIPGAP);
1.892 + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_GOMORY)
1.893 + parm.gmi_cuts = GLP_ON;
1.894 + else
1.895 + parm.gmi_cuts = GLP_OFF;
1.896 + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_MIR)
1.897 + parm.mir_cuts = GLP_ON;
1.898 + else
1.899 + parm.mir_cuts = GLP_OFF;
1.900 + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_COVER)
1.901 + parm.cov_cuts = GLP_ON;
1.902 + else
1.903 + parm.cov_cuts = GLP_OFF;
1.904 + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_CLIQUE)
1.905 + parm.clq_cuts = GLP_ON;
1.906 + else
1.907 + parm.clq_cuts = GLP_OFF;
1.908 + parm.presolve = presolve;
1.909 + if (lpx_get_int_parm(lp, LPX_K_BINARIZE))
1.910 + parm.binarize = GLP_ON;
1.911 + ret = glp_intopt(lp, &parm);
1.912 + switch (ret)
1.913 + { case 0: ret = LPX_E_OK; break;
1.914 + case GLP_ENOPFS: ret = LPX_E_NOPFS; break;
1.915 + case GLP_ENODFS: ret = LPX_E_NODFS; break;
1.916 + case GLP_EBOUND:
1.917 + case GLP_EROOT: ret = LPX_E_FAULT; break;
1.918 + case GLP_EFAIL: ret = LPX_E_SING; break;
1.919 + case GLP_EMIPGAP: ret = LPX_E_MIPGAP; break;
1.920 + case GLP_ETMLIM: ret = LPX_E_TMLIM; break;
1.921 + default: xassert(ret != ret);
1.922 + }
1.923 + return ret;
1.924 +}
1.925 +
1.926 +int lpx_integer(LPX *lp)
1.927 +{ /* easy-to-use driver to the branch-and-bound method */
1.928 + return solve_mip(lp, GLP_OFF);
1.929 +}
1.930 +
1.931 +int lpx_intopt(LPX *lp)
1.932 +{ /* easy-to-use driver to the branch-and-bound method */
1.933 + return solve_mip(lp, GLP_ON);
1.934 +}
1.935 +
1.936 +int lpx_mip_status(glp_prob *lp)
1.937 +{ /* retrieve status of MIP solution */
1.938 + int status;
1.939 + switch (glp_mip_status(lp))
1.940 + { case GLP_UNDEF: status = LPX_I_UNDEF; break;
1.941 + case GLP_OPT: status = LPX_I_OPT; break;
1.942 + case GLP_FEAS: status = LPX_I_FEAS; break;
1.943 + case GLP_NOFEAS: status = LPX_I_NOFEAS; break;
1.944 + default: xassert(lp != lp);
1.945 + }
1.946 + return status;
1.947 +}
1.948 +
1.949 +double lpx_mip_obj_val(LPX *lp)
1.950 +{ /* retrieve objective value (MIP solution) */
1.951 + return glp_mip_obj_val(lp);
1.952 +}
1.953 +
1.954 +double lpx_mip_row_val(LPX *lp, int i)
1.955 +{ /* retrieve row value (MIP solution) */
1.956 + return glp_mip_row_val(lp, i);
1.957 +}
1.958 +
1.959 +double lpx_mip_col_val(LPX *lp, int j)
1.960 +{ /* retrieve column value (MIP solution) */
1.961 + return glp_mip_col_val(lp, j);
1.962 +}
1.963 +
1.964 +void lpx_check_int(LPX *lp, LPXKKT *kkt)
1.965 +{ /* check integer feasibility conditions */
1.966 + int ae_ind, re_ind;
1.967 + double ae_max, re_max;
1.968 + _glp_check_kkt(lp, GLP_MIP, GLP_KKT_PE, &ae_max, &ae_ind, &re_max,
1.969 + &re_ind);
1.970 + kkt->pe_ae_max = ae_max;
1.971 + kkt->pe_ae_row = ae_ind;
1.972 + kkt->pe_re_max = re_max;
1.973 + kkt->pe_re_row = re_ind;
1.974 + if (re_max <= 1e-9)
1.975 + kkt->pe_quality = 'H';
1.976 + else if (re_max <= 1e-6)
1.977 + kkt->pe_quality = 'M';
1.978 + else if (re_max <= 1e-3)
1.979 + kkt->pe_quality = 'L';
1.980 + else
1.981 + kkt->pe_quality = '?';
1.982 + _glp_check_kkt(lp, GLP_MIP, GLP_KKT_PB, &ae_max, &ae_ind, &re_max,
1.983 + &re_ind);
1.984 + kkt->pb_ae_max = ae_max;
1.985 + kkt->pb_ae_ind = ae_ind;
1.986 + kkt->pb_re_max = re_max;
1.987 + kkt->pb_re_ind = re_ind;
1.988 + if (re_max <= 1e-9)
1.989 + kkt->pb_quality = 'H';
1.990 + else if (re_max <= 1e-6)
1.991 + kkt->pb_quality = 'M';
1.992 + else if (re_max <= 1e-3)
1.993 + kkt->pb_quality = 'L';
1.994 + else
1.995 + kkt->pb_quality = '?';
1.996 + return;
1.997 +}
1.998 +
1.999 +#if 1 /* 17/XI-2009 */
1.1000 +static void reset_parms(LPX *lp)
1.1001 +{ /* reset control parameters to default values */
1.1002 + struct LPXCPS *cps = lp->parms;
1.1003 + xassert(cps != NULL);
1.1004 + cps->msg_lev = 3;
1.1005 + cps->scale = 1;
1.1006 + cps->dual = 0;
1.1007 + cps->price = 1;
1.1008 + cps->relax = 0.07;
1.1009 + cps->tol_bnd = 1e-7;
1.1010 + cps->tol_dj = 1e-7;
1.1011 + cps->tol_piv = 1e-9;
1.1012 + cps->round = 0;
1.1013 + cps->obj_ll = -DBL_MAX;
1.1014 + cps->obj_ul = +DBL_MAX;
1.1015 + cps->it_lim = -1;
1.1016 +#if 0 /* 02/XII-2010 */
1.1017 + lp->it_cnt = 0;
1.1018 +#endif
1.1019 + cps->tm_lim = -1.0;
1.1020 + cps->out_frq = 200;
1.1021 + cps->out_dly = 0.0;
1.1022 + cps->branch = 2;
1.1023 + cps->btrack = 3;
1.1024 + cps->tol_int = 1e-5;
1.1025 + cps->tol_obj = 1e-7;
1.1026 + cps->mps_info = 1;
1.1027 + cps->mps_obj = 2;
1.1028 + cps->mps_orig = 0;
1.1029 + cps->mps_wide = 1;
1.1030 + cps->mps_free = 0;
1.1031 + cps->mps_skip = 0;
1.1032 + cps->lpt_orig = 0;
1.1033 + cps->presol = 0;
1.1034 + cps->binarize = 0;
1.1035 + cps->use_cuts = 0;
1.1036 + cps->mip_gap = 0.0;
1.1037 + return;
1.1038 +}
1.1039 +#endif
1.1040 +
1.1041 +#if 1 /* 17/XI-2009 */
1.1042 +static struct LPXCPS *access_parms(LPX *lp)
1.1043 +{ /* allocate and initialize control parameters, if necessary */
1.1044 + if (lp->parms == NULL)
1.1045 + { lp->parms = xmalloc(sizeof(struct LPXCPS));
1.1046 + reset_parms(lp);
1.1047 + }
1.1048 + return lp->parms;
1.1049 +}
1.1050 +#endif
1.1051 +
1.1052 +#if 1 /* 17/XI-2009 */
1.1053 +void lpx_reset_parms(LPX *lp)
1.1054 +{ /* reset control parameters to default values */
1.1055 + access_parms(lp);
1.1056 + reset_parms(lp);
1.1057 + return;
1.1058 +}
1.1059 +#endif
1.1060 +
1.1061 +void lpx_set_int_parm(LPX *lp, int parm, int val)
1.1062 +{ /* set (change) integer control parameter */
1.1063 +#if 0 /* 17/XI-2009 */
1.1064 + struct LPXCPS *cps = lp->cps;
1.1065 +#else
1.1066 + struct LPXCPS *cps = access_parms(lp);
1.1067 +#endif
1.1068 + switch (parm)
1.1069 + { case LPX_K_MSGLEV:
1.1070 + if (!(0 <= val && val <= 3))
1.1071 + xerror("lpx_set_int_parm: MSGLEV = %d; invalid value\n",
1.1072 + val);
1.1073 + cps->msg_lev = val;
1.1074 + break;
1.1075 + case LPX_K_SCALE:
1.1076 + if (!(0 <= val && val <= 3))
1.1077 + xerror("lpx_set_int_parm: SCALE = %d; invalid value\n",
1.1078 + val);
1.1079 + cps->scale = val;
1.1080 + break;
1.1081 + case LPX_K_DUAL:
1.1082 + if (!(val == 0 || val == 1))
1.1083 + xerror("lpx_set_int_parm: DUAL = %d; invalid value\n",
1.1084 + val);
1.1085 + cps->dual = val;
1.1086 + break;
1.1087 + case LPX_K_PRICE:
1.1088 + if (!(val == 0 || val == 1))
1.1089 + xerror("lpx_set_int_parm: PRICE = %d; invalid value\n",
1.1090 + val);
1.1091 + cps->price = val;
1.1092 + break;
1.1093 + case LPX_K_ROUND:
1.1094 + if (!(val == 0 || val == 1))
1.1095 + xerror("lpx_set_int_parm: ROUND = %d; invalid value\n",
1.1096 + val);
1.1097 + cps->round = val;
1.1098 + break;
1.1099 + case LPX_K_ITLIM:
1.1100 + cps->it_lim = val;
1.1101 + break;
1.1102 + case LPX_K_ITCNT:
1.1103 + lp->it_cnt = val;
1.1104 + break;
1.1105 + case LPX_K_OUTFRQ:
1.1106 + if (!(val > 0))
1.1107 + xerror("lpx_set_int_parm: OUTFRQ = %d; invalid value\n",
1.1108 + val);
1.1109 + cps->out_frq = val;
1.1110 + break;
1.1111 + case LPX_K_BRANCH:
1.1112 + if (!(val == 0 || val == 1 || val == 2 || val == 3))
1.1113 + xerror("lpx_set_int_parm: BRANCH = %d; invalid value\n",
1.1114 + val);
1.1115 + cps->branch = val;
1.1116 + break;
1.1117 + case LPX_K_BTRACK:
1.1118 + if (!(val == 0 || val == 1 || val == 2 || val == 3))
1.1119 + xerror("lpx_set_int_parm: BTRACK = %d; invalid value\n",
1.1120 + val);
1.1121 + cps->btrack = val;
1.1122 + break;
1.1123 + case LPX_K_MPSINFO:
1.1124 + if (!(val == 0 || val == 1))
1.1125 + xerror("lpx_set_int_parm: MPSINFO = %d; invalid value\n",
1.1126 + val);
1.1127 + cps->mps_info = val;
1.1128 + break;
1.1129 + case LPX_K_MPSOBJ:
1.1130 + if (!(val == 0 || val == 1 || val == 2))
1.1131 + xerror("lpx_set_int_parm: MPSOBJ = %d; invalid value\n",
1.1132 + val);
1.1133 + cps->mps_obj = val;
1.1134 + break;
1.1135 + case LPX_K_MPSORIG:
1.1136 + if (!(val == 0 || val == 1))
1.1137 + xerror("lpx_set_int_parm: MPSORIG = %d; invalid value\n",
1.1138 + val);
1.1139 + cps->mps_orig = val;
1.1140 + break;
1.1141 + case LPX_K_MPSWIDE:
1.1142 + if (!(val == 0 || val == 1))
1.1143 + xerror("lpx_set_int_parm: MPSWIDE = %d; invalid value\n",
1.1144 + val);
1.1145 + cps->mps_wide = val;
1.1146 + break;
1.1147 + case LPX_K_MPSFREE:
1.1148 + if (!(val == 0 || val == 1))
1.1149 + xerror("lpx_set_int_parm: MPSFREE = %d; invalid value\n",
1.1150 + val);
1.1151 + cps->mps_free = val;
1.1152 + break;
1.1153 + case LPX_K_MPSSKIP:
1.1154 + if (!(val == 0 || val == 1))
1.1155 + xerror("lpx_set_int_parm: MPSSKIP = %d; invalid value\n",
1.1156 + val);
1.1157 + cps->mps_skip = val;
1.1158 + break;
1.1159 + case LPX_K_LPTORIG:
1.1160 + if (!(val == 0 || val == 1))
1.1161 + xerror("lpx_set_int_parm: LPTORIG = %d; invalid value\n",
1.1162 + val);
1.1163 + cps->lpt_orig = val;
1.1164 + break;
1.1165 + case LPX_K_PRESOL:
1.1166 + if (!(val == 0 || val == 1))
1.1167 + xerror("lpx_set_int_parm: PRESOL = %d; invalid value\n",
1.1168 + val);
1.1169 + cps->presol = val;
1.1170 + break;
1.1171 + case LPX_K_BINARIZE:
1.1172 + if (!(val == 0 || val == 1))
1.1173 + xerror("lpx_set_int_parm: BINARIZE = %d; invalid value\n"
1.1174 + , val);
1.1175 + cps->binarize = val;
1.1176 + break;
1.1177 + case LPX_K_USECUTS:
1.1178 + if (val & ~LPX_C_ALL)
1.1179 + xerror("lpx_set_int_parm: USECUTS = 0x%X; invalid value\n",
1.1180 + val);
1.1181 + cps->use_cuts = val;
1.1182 + break;
1.1183 + case LPX_K_BFTYPE:
1.1184 +#if 0
1.1185 + if (!(1 <= val && val <= 3))
1.1186 + xerror("lpx_set_int_parm: BFTYPE = %d; invalid value\n",
1.1187 + val);
1.1188 + cps->bf_type = val;
1.1189 +#else
1.1190 + { glp_bfcp parm;
1.1191 + glp_get_bfcp(lp, &parm);
1.1192 + switch (val)
1.1193 + { case 1:
1.1194 + parm.type = GLP_BF_FT; break;
1.1195 + case 2:
1.1196 + parm.type = GLP_BF_BG; break;
1.1197 + case 3:
1.1198 + parm.type = GLP_BF_GR; break;
1.1199 + default:
1.1200 + xerror("lpx_set_int_parm: BFTYPE = %d; invalid val"
1.1201 + "ue\n", val);
1.1202 + }
1.1203 + glp_set_bfcp(lp, &parm);
1.1204 + }
1.1205 +#endif
1.1206 + break;
1.1207 + default:
1.1208 + xerror("lpx_set_int_parm: parm = %d; invalid parameter\n",
1.1209 + parm);
1.1210 + }
1.1211 + return;
1.1212 +}
1.1213 +
1.1214 +int lpx_get_int_parm(LPX *lp, int parm)
1.1215 +{ /* query integer control parameter */
1.1216 +#if 0 /* 17/XI-2009 */
1.1217 + struct LPXCPS *cps = lp->cps;
1.1218 +#else
1.1219 + struct LPXCPS *cps = access_parms(lp);
1.1220 +#endif
1.1221 + int val = 0;
1.1222 + switch (parm)
1.1223 + { case LPX_K_MSGLEV:
1.1224 + val = cps->msg_lev; break;
1.1225 + case LPX_K_SCALE:
1.1226 + val = cps->scale; break;
1.1227 + case LPX_K_DUAL:
1.1228 + val = cps->dual; break;
1.1229 + case LPX_K_PRICE:
1.1230 + val = cps->price; break;
1.1231 + case LPX_K_ROUND:
1.1232 + val = cps->round; break;
1.1233 + case LPX_K_ITLIM:
1.1234 + val = cps->it_lim; break;
1.1235 + case LPX_K_ITCNT:
1.1236 + val = lp->it_cnt; break;
1.1237 + case LPX_K_OUTFRQ:
1.1238 + val = cps->out_frq; break;
1.1239 + case LPX_K_BRANCH:
1.1240 + val = cps->branch; break;
1.1241 + case LPX_K_BTRACK:
1.1242 + val = cps->btrack; break;
1.1243 + case LPX_K_MPSINFO:
1.1244 + val = cps->mps_info; break;
1.1245 + case LPX_K_MPSOBJ:
1.1246 + val = cps->mps_obj; break;
1.1247 + case LPX_K_MPSORIG:
1.1248 + val = cps->mps_orig; break;
1.1249 + case LPX_K_MPSWIDE:
1.1250 + val = cps->mps_wide; break;
1.1251 + case LPX_K_MPSFREE:
1.1252 + val = cps->mps_free; break;
1.1253 + case LPX_K_MPSSKIP:
1.1254 + val = cps->mps_skip; break;
1.1255 + case LPX_K_LPTORIG:
1.1256 + val = cps->lpt_orig; break;
1.1257 + case LPX_K_PRESOL:
1.1258 + val = cps->presol; break;
1.1259 + case LPX_K_BINARIZE:
1.1260 + val = cps->binarize; break;
1.1261 + case LPX_K_USECUTS:
1.1262 + val = cps->use_cuts; break;
1.1263 + case LPX_K_BFTYPE:
1.1264 +#if 0
1.1265 + val = cps->bf_type; break;
1.1266 +#else
1.1267 + { glp_bfcp parm;
1.1268 + glp_get_bfcp(lp, &parm);
1.1269 + switch (parm.type)
1.1270 + { case GLP_BF_FT:
1.1271 + val = 1; break;
1.1272 + case GLP_BF_BG:
1.1273 + val = 2; break;
1.1274 + case GLP_BF_GR:
1.1275 + val = 3; break;
1.1276 + default:
1.1277 + xassert(lp != lp);
1.1278 + }
1.1279 + }
1.1280 + break;
1.1281 +#endif
1.1282 + default:
1.1283 + xerror("lpx_get_int_parm: parm = %d; invalid parameter\n",
1.1284 + parm);
1.1285 + }
1.1286 + return val;
1.1287 +}
1.1288 +
1.1289 +void lpx_set_real_parm(LPX *lp, int parm, double val)
1.1290 +{ /* set (change) real control parameter */
1.1291 +#if 0 /* 17/XI-2009 */
1.1292 + struct LPXCPS *cps = lp->cps;
1.1293 +#else
1.1294 + struct LPXCPS *cps = access_parms(lp);
1.1295 +#endif
1.1296 + switch (parm)
1.1297 + { case LPX_K_RELAX:
1.1298 + if (!(0.0 <= val && val <= 1.0))
1.1299 + xerror("lpx_set_real_parm: RELAX = %g; invalid value\n",
1.1300 + val);
1.1301 + cps->relax = val;
1.1302 + break;
1.1303 + case LPX_K_TOLBND:
1.1304 + if (!(DBL_EPSILON <= val && val <= 0.001))
1.1305 + xerror("lpx_set_real_parm: TOLBND = %g; invalid value\n",
1.1306 + val);
1.1307 +#if 0
1.1308 + if (cps->tol_bnd > val)
1.1309 + { /* invalidate the basic solution */
1.1310 + lp->p_stat = LPX_P_UNDEF;
1.1311 + lp->d_stat = LPX_D_UNDEF;
1.1312 + }
1.1313 +#endif
1.1314 + cps->tol_bnd = val;
1.1315 + break;
1.1316 + case LPX_K_TOLDJ:
1.1317 + if (!(DBL_EPSILON <= val && val <= 0.001))
1.1318 + xerror("lpx_set_real_parm: TOLDJ = %g; invalid value\n",
1.1319 + val);
1.1320 +#if 0
1.1321 + if (cps->tol_dj > val)
1.1322 + { /* invalidate the basic solution */
1.1323 + lp->p_stat = LPX_P_UNDEF;
1.1324 + lp->d_stat = LPX_D_UNDEF;
1.1325 + }
1.1326 +#endif
1.1327 + cps->tol_dj = val;
1.1328 + break;
1.1329 + case LPX_K_TOLPIV:
1.1330 + if (!(DBL_EPSILON <= val && val <= 0.001))
1.1331 + xerror("lpx_set_real_parm: TOLPIV = %g; invalid value\n",
1.1332 + val);
1.1333 + cps->tol_piv = val;
1.1334 + break;
1.1335 + case LPX_K_OBJLL:
1.1336 + cps->obj_ll = val;
1.1337 + break;
1.1338 + case LPX_K_OBJUL:
1.1339 + cps->obj_ul = val;
1.1340 + break;
1.1341 + case LPX_K_TMLIM:
1.1342 + cps->tm_lim = val;
1.1343 + break;
1.1344 + case LPX_K_OUTDLY:
1.1345 + cps->out_dly = val;
1.1346 + break;
1.1347 + case LPX_K_TOLINT:
1.1348 + if (!(DBL_EPSILON <= val && val <= 0.001))
1.1349 + xerror("lpx_set_real_parm: TOLINT = %g; invalid value\n",
1.1350 + val);
1.1351 + cps->tol_int = val;
1.1352 + break;
1.1353 + case LPX_K_TOLOBJ:
1.1354 + if (!(DBL_EPSILON <= val && val <= 0.001))
1.1355 + xerror("lpx_set_real_parm: TOLOBJ = %g; invalid value\n",
1.1356 + val);
1.1357 + cps->tol_obj = val;
1.1358 + break;
1.1359 + case LPX_K_MIPGAP:
1.1360 + if (val < 0.0)
1.1361 + xerror("lpx_set_real_parm: MIPGAP = %g; invalid value\n",
1.1362 + val);
1.1363 + cps->mip_gap = val;
1.1364 + break;
1.1365 + default:
1.1366 + xerror("lpx_set_real_parm: parm = %d; invalid parameter\n",
1.1367 + parm);
1.1368 + }
1.1369 + return;
1.1370 +}
1.1371 +
1.1372 +double lpx_get_real_parm(LPX *lp, int parm)
1.1373 +{ /* query real control parameter */
1.1374 +#if 0 /* 17/XI-2009 */
1.1375 + struct LPXCPS *cps = lp->cps;
1.1376 +#else
1.1377 + struct LPXCPS *cps = access_parms(lp);
1.1378 +#endif
1.1379 + double val = 0.0;
1.1380 + switch (parm)
1.1381 + { case LPX_K_RELAX:
1.1382 + val = cps->relax;
1.1383 + break;
1.1384 + case LPX_K_TOLBND:
1.1385 + val = cps->tol_bnd;
1.1386 + break;
1.1387 + case LPX_K_TOLDJ:
1.1388 + val = cps->tol_dj;
1.1389 + break;
1.1390 + case LPX_K_TOLPIV:
1.1391 + val = cps->tol_piv;
1.1392 + break;
1.1393 + case LPX_K_OBJLL:
1.1394 + val = cps->obj_ll;
1.1395 + break;
1.1396 + case LPX_K_OBJUL:
1.1397 + val = cps->obj_ul;
1.1398 + break;
1.1399 + case LPX_K_TMLIM:
1.1400 + val = cps->tm_lim;
1.1401 + break;
1.1402 + case LPX_K_OUTDLY:
1.1403 + val = cps->out_dly;
1.1404 + break;
1.1405 + case LPX_K_TOLINT:
1.1406 + val = cps->tol_int;
1.1407 + break;
1.1408 + case LPX_K_TOLOBJ:
1.1409 + val = cps->tol_obj;
1.1410 + break;
1.1411 + case LPX_K_MIPGAP:
1.1412 + val = cps->mip_gap;
1.1413 + break;
1.1414 + default:
1.1415 + xerror("lpx_get_real_parm: parm = %d; invalid parameter\n",
1.1416 + parm);
1.1417 + }
1.1418 + return val;
1.1419 +}
1.1420 +
1.1421 +LPX *lpx_read_mps(const char *fname)
1.1422 +{ /* read problem data in fixed MPS format */
1.1423 + LPX *lp = lpx_create_prob();
1.1424 + if (glp_read_mps(lp, GLP_MPS_DECK, NULL, fname))
1.1425 + lpx_delete_prob(lp), lp = NULL;
1.1426 + return lp;
1.1427 +}
1.1428 +
1.1429 +int lpx_write_mps(LPX *lp, const char *fname)
1.1430 +{ /* write problem data in fixed MPS format */
1.1431 + return glp_write_mps(lp, GLP_MPS_DECK, NULL, fname);
1.1432 +}
1.1433 +
1.1434 +int lpx_read_bas(LPX *lp, const char *fname)
1.1435 +{ /* read LP basis in fixed MPS format */
1.1436 +#if 0 /* 13/IV-2009 */
1.1437 + return read_bas(lp, fname);
1.1438 +#else
1.1439 + xassert(lp == lp);
1.1440 + xassert(fname == fname);
1.1441 + xerror("lpx_read_bas: operation not supported\n");
1.1442 + return 0;
1.1443 +#endif
1.1444 +}
1.1445 +
1.1446 +int lpx_write_bas(LPX *lp, const char *fname)
1.1447 +{ /* write LP basis in fixed MPS format */
1.1448 +#if 0 /* 13/IV-2009 */
1.1449 + return write_bas(lp, fname);
1.1450 +#else
1.1451 + xassert(lp == lp);
1.1452 + xassert(fname == fname);
1.1453 + xerror("lpx_write_bas: operation not supported\n");
1.1454 + return 0;
1.1455 +#endif
1.1456 +}
1.1457 +
1.1458 +LPX *lpx_read_freemps(const char *fname)
1.1459 +{ /* read problem data in free MPS format */
1.1460 + LPX *lp = lpx_create_prob();
1.1461 + if (glp_read_mps(lp, GLP_MPS_FILE, NULL, fname))
1.1462 + lpx_delete_prob(lp), lp = NULL;
1.1463 + return lp;
1.1464 +}
1.1465 +
1.1466 +int lpx_write_freemps(LPX *lp, const char *fname)
1.1467 +{ /* write problem data in free MPS format */
1.1468 + return glp_write_mps(lp, GLP_MPS_FILE, NULL, fname);
1.1469 +}
1.1470 +
1.1471 +LPX *lpx_read_cpxlp(const char *fname)
1.1472 +{ /* read problem data in CPLEX LP format */
1.1473 + LPX *lp;
1.1474 + lp = lpx_create_prob();
1.1475 + if (glp_read_lp(lp, NULL, fname))
1.1476 + lpx_delete_prob(lp), lp = NULL;
1.1477 + return lp;
1.1478 +}
1.1479 +
1.1480 +int lpx_write_cpxlp(LPX *lp, const char *fname)
1.1481 +{ /* write problem data in CPLEX LP format */
1.1482 + return glp_write_lp(lp, NULL, fname);
1.1483 +}
1.1484 +
1.1485 +LPX *lpx_read_model(const char *model, const char *data, const char
1.1486 + *output)
1.1487 +{ /* read LP/MIP model written in GNU MathProg language */
1.1488 + LPX *lp = NULL;
1.1489 + glp_tran *tran;
1.1490 + /* allocate the translator workspace */
1.1491 + tran = glp_mpl_alloc_wksp();
1.1492 + /* read model section and optional data section */
1.1493 + if (glp_mpl_read_model(tran, model, data != NULL)) goto done;
1.1494 + /* read separate data section, if required */
1.1495 + if (data != NULL)
1.1496 + if (glp_mpl_read_data(tran, data)) goto done;
1.1497 + /* generate the model */
1.1498 + if (glp_mpl_generate(tran, output)) goto done;
1.1499 + /* build the problem instance from the model */
1.1500 + lp = glp_create_prob();
1.1501 + glp_mpl_build_prob(tran, lp);
1.1502 +done: /* free the translator workspace */
1.1503 + glp_mpl_free_wksp(tran);
1.1504 + /* bring the problem object to the calling program */
1.1505 + return lp;
1.1506 +}
1.1507 +
1.1508 +int lpx_print_prob(LPX *lp, const char *fname)
1.1509 +{ /* write problem data in plain text format */
1.1510 + return glp_write_lp(lp, NULL, fname);
1.1511 +}
1.1512 +
1.1513 +int lpx_print_sol(LPX *lp, const char *fname)
1.1514 +{ /* write LP problem solution in printable format */
1.1515 + return glp_print_sol(lp, fname);
1.1516 +}
1.1517 +
1.1518 +int lpx_print_sens_bnds(LPX *lp, const char *fname)
1.1519 +{ /* write bounds sensitivity information */
1.1520 + if (glp_get_status(lp) == GLP_OPT && !glp_bf_exists(lp))
1.1521 + glp_factorize(lp);
1.1522 + return glp_print_ranges(lp, 0, NULL, 0, fname);
1.1523 +}
1.1524 +
1.1525 +int lpx_print_ips(LPX *lp, const char *fname)
1.1526 +{ /* write interior point solution in printable format */
1.1527 + return glp_print_ipt(lp, fname);
1.1528 +}
1.1529 +
1.1530 +int lpx_print_mip(LPX *lp, const char *fname)
1.1531 +{ /* write MIP problem solution in printable format */
1.1532 + return glp_print_mip(lp, fname);
1.1533 +}
1.1534 +
1.1535 +int lpx_is_b_avail(glp_prob *lp)
1.1536 +{ /* check if LP basis is available */
1.1537 + return glp_bf_exists(lp);
1.1538 +}
1.1539 +
1.1540 +int lpx_main(int argc, const char *argv[])
1.1541 +{ /* stand-alone LP/MIP solver */
1.1542 + return glp_main(argc, argv);
1.1543 +}
1.1544 +
1.1545 +/* eof */