src/glplpx01.c
author Alpar Juttner <alpar@cs.elte.hu>
Mon, 06 Dec 2010 13:09:21 +0100
changeset 1 c445c931472f
permissions -rw-r--r--
Import glpk-4.45

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