src/lemon/lp_glpk.cc
author ladanyi
Fri, 22 Apr 2005 16:20:12 +0000
changeset 1380 cb2891afe526
parent 1377 bfbb5b30c5b8
child 1405 3626c7f10f14
permissions -rw-r--r--
added check for CLPEX
athos@1261
     1
/* -*- C++ -*-
athos@1261
     2
 * src/lemon/lp_glpk.cc - Part of LEMON, a generic C++ optimization library
athos@1261
     3
 *
athos@1261
     4
 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359
     5
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
athos@1261
     6
 *
athos@1261
     7
 * Permission to use, modify and distribute this software is granted
athos@1261
     8
 * provided that this copyright notice appears in all copies. For
athos@1261
     9
 * precise terms see the accompanying LICENSE file.
athos@1261
    10
 *
athos@1261
    11
 * This software is provided "AS IS" with no warranty of any kind,
athos@1261
    12
 * express or implied, and with no claim as to its suitability for any
athos@1261
    13
 * purpose.
athos@1261
    14
 *
athos@1261
    15
 */
athos@1261
    16
athos@1261
    17
#ifndef LEMON_LP_GLPK_CC
athos@1261
    18
#define LEMON_LP_GLPK_CC
athos@1261
    19
athos@1261
    20
///\file
athos@1261
    21
///\brief Implementation of the LEMON-GLPK lp solver interface.
athos@1261
    22
ladanyi@1305
    23
#include <lemon/lp_glpk.h>
athos@1261
    24
athos@1261
    25
namespace lemon {
athos@1261
    26
alpar@1364
    27
  ///\e
alpar@1364
    28
alpar@1364
    29
  ///\bug Unimplemented!
alpar@1364
    30
  ///
alpar@1364
    31
  LpSolverBase &LpGlpk::_newLp()
alpar@1364
    32
  {
alpar@1368
    33
    LpSolverBase *tmp=0;
alpar@1368
    34
    return *tmp;
alpar@1364
    35
  }
alpar@1364
    36
  
alpar@1364
    37
  ///\e
alpar@1364
    38
alpar@1364
    39
  ///\bug Unimplemented!
alpar@1364
    40
  ///
alpar@1364
    41
  LpSolverBase &LpGlpk::_copyLp()
alpar@1364
    42
  {
alpar@1368
    43
    LpSolverBase *tmp=0;
alpar@1368
    44
    return *tmp;
alpar@1364
    45
  }
alpar@1364
    46
alpar@1321
    47
  LpGlpk::LpGlpk() : Parent(), 
alpar@1321
    48
		     lp(lpx_create_prob()) {
alpar@1321
    49
    ///\todo constrol function for this:
alpar@1321
    50
    lpx_set_int_parm(lp, LPX_K_DUAL, 1);
alpar@1321
    51
    messageLevel(0);
alpar@1321
    52
  }
alpar@1321
    53
  
alpar@1321
    54
  LpGlpk::~LpGlpk() {
alpar@1321
    55
    lpx_delete_prob(lp);
alpar@1321
    56
  }
alpar@1321
    57
  
alpar@1321
    58
  int LpGlpk::_addCol() { 
alpar@1321
    59
    int i=lpx_add_cols(lp, 1);
alpar@1321
    60
    _setColLowerBound(i, -INF);
alpar@1321
    61
    _setColUpperBound(i, INF);
alpar@1321
    62
    return i;
alpar@1321
    63
  }
alpar@1321
    64
alpar@1321
    65
  int LpGlpk::_addRow() { 
alpar@1321
    66
    int i=lpx_add_rows(lp, 1);
alpar@1321
    67
    return i;
alpar@1321
    68
  }
alpar@1321
    69
alpar@1321
    70
  
alpar@1321
    71
  void LpGlpk::_setRowCoeffs(int i, 
alpar@1321
    72
			     int length,
alpar@1321
    73
			     const int   * indices, 
alpar@1321
    74
			     const Value   * values )
alpar@1321
    75
  {
alpar@1321
    76
    lpx_set_mat_row(lp, i, length,
alpar@1321
    77
		    const_cast<int * >(indices) ,
alpar@1321
    78
		    const_cast<Value * >(values));
alpar@1321
    79
  }
alpar@1321
    80
  
alpar@1321
    81
  void LpGlpk::_setColCoeffs(int i, 
alpar@1321
    82
			     int length,
alpar@1321
    83
			     const int   * indices, 
alpar@1321
    84
			     const Value   * values)
alpar@1321
    85
  {
alpar@1321
    86
    lpx_set_mat_col(lp, i, length,
alpar@1321
    87
		    const_cast<int * >(indices),
alpar@1321
    88
		    const_cast<Value * >(values));
alpar@1321
    89
  }
alpar@1321
    90
  
alpar@1321
    91
  void LpGlpk::_setColLowerBound(int i, Value lo)
alpar@1321
    92
  {
alpar@1321
    93
    if (lo==INF) {
alpar@1321
    94
      //FIXME error
alpar@1321
    95
    }
alpar@1321
    96
    int b=lpx_get_col_type(lp, i);
alpar@1321
    97
    double up=lpx_get_col_ub(lp, i);	
alpar@1321
    98
    if (lo==-INF) {
alpar@1321
    99
      switch (b) {
alpar@1321
   100
      case LPX_FR:
alpar@1321
   101
      case LPX_LO:
alpar@1321
   102
	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
alpar@1321
   103
	break;
alpar@1321
   104
      case LPX_UP:
alpar@1321
   105
	break;
alpar@1321
   106
      case LPX_DB:
alpar@1321
   107
      case LPX_FX:
alpar@1321
   108
	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
alpar@1321
   109
	break;
alpar@1321
   110
      default: ;
alpar@1321
   111
	//FIXME error
alpar@1321
   112
      }
alpar@1321
   113
    } else {
alpar@1321
   114
      switch (b) {
alpar@1321
   115
      case LPX_FR:
alpar@1321
   116
      case LPX_LO:
alpar@1321
   117
	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
alpar@1321
   118
	break;
alpar@1321
   119
      case LPX_UP:	  
alpar@1321
   120
      case LPX_DB:
alpar@1321
   121
      case LPX_FX:
alpar@1321
   122
	if (lo==up) 
alpar@1321
   123
	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
alpar@1321
   124
	else 
alpar@1321
   125
	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
alpar@1321
   126
	break;
alpar@1321
   127
      default: ;
alpar@1321
   128
	//FIXME error
alpar@1321
   129
      }
athos@1261
   130
    }
athos@1261
   131
alpar@1321
   132
  }
alpar@1321
   133
  
alpar@1321
   134
  void LpGlpk::_setColUpperBound(int i, Value up)
alpar@1321
   135
  {
alpar@1321
   136
    if (up==-INF) {
alpar@1321
   137
      //FIXME error
athos@1261
   138
    }
alpar@1321
   139
    int b=lpx_get_col_type(lp, i);
alpar@1321
   140
    double lo=lpx_get_col_lb(lp, i);
alpar@1321
   141
    if (up==INF) {
alpar@1321
   142
      switch (b) {
alpar@1321
   143
      case LPX_FR:
alpar@1321
   144
      case LPX_LO:
alpar@1321
   145
	break;
alpar@1321
   146
      case LPX_UP:
alpar@1321
   147
	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
alpar@1321
   148
	break;
alpar@1321
   149
      case LPX_DB:
alpar@1321
   150
      case LPX_FX:
alpar@1321
   151
	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
alpar@1321
   152
	break;
alpar@1321
   153
      default: ;
athos@1261
   154
	//FIXME error
athos@1261
   155
      }
alpar@1321
   156
    } else {
alpar@1321
   157
      switch (b) {
alpar@1321
   158
      case LPX_FR:
alpar@1321
   159
	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
alpar@1321
   160
	break;
alpar@1321
   161
      case LPX_UP:
alpar@1321
   162
	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
alpar@1321
   163
	break;
alpar@1321
   164
      case LPX_LO:
alpar@1321
   165
      case LPX_DB:
alpar@1321
   166
      case LPX_FX:
alpar@1321
   167
	if (lo==up) 
alpar@1321
   168
	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
alpar@1321
   169
	else 
alpar@1321
   170
	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
alpar@1321
   171
	break;
alpar@1321
   172
      default: ;
athos@1261
   173
	//FIXME error
athos@1261
   174
      }
alpar@1321
   175
    }
alpar@1321
   176
  }
alpar@1321
   177
  
alpar@1321
   178
  void LpGlpk::_setRowLowerBound(int i, Value lo)
alpar@1321
   179
  {
alpar@1321
   180
    if (lo==INF) {
alpar@1321
   181
      //FIXME error
alpar@1321
   182
    }
alpar@1321
   183
    int b=lpx_get_row_type(lp, i);
alpar@1321
   184
    double up=lpx_get_row_ub(lp, i);	
alpar@1321
   185
    if (lo==-INF) {
alpar@1321
   186
      switch (b) {
alpar@1321
   187
      case LPX_FR:
alpar@1321
   188
      case LPX_LO:
alpar@1321
   189
	lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
alpar@1321
   190
	break;
alpar@1321
   191
      case LPX_UP:
alpar@1321
   192
	break;
alpar@1321
   193
      case LPX_DB:
alpar@1321
   194
      case LPX_FX:
alpar@1321
   195
	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
alpar@1321
   196
	break;
alpar@1321
   197
      default: ;
alpar@1321
   198
	//FIXME error
alpar@1321
   199
      }
alpar@1321
   200
    } else {
alpar@1321
   201
      switch (b) {
alpar@1321
   202
      case LPX_FR:
alpar@1321
   203
      case LPX_LO:
alpar@1321
   204
	lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
alpar@1321
   205
	break;
alpar@1321
   206
      case LPX_UP:	  
alpar@1321
   207
      case LPX_DB:
alpar@1321
   208
      case LPX_FX:
alpar@1321
   209
	if (lo==up) 
alpar@1321
   210
	  lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
alpar@1321
   211
	else 
alpar@1321
   212
	  lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
alpar@1321
   213
	break;
alpar@1321
   214
      default: ;
alpar@1321
   215
	//FIXME error
athos@1261
   216
      }
athos@1261
   217
    }
alpar@1321
   218
  }
athos@1261
   219
  
athos@1298
   220
  void LpGlpk::_setRowUpperBound(int i, Value up)
athos@1298
   221
  {
athos@1298
   222
    if (up==-INF) {
athos@1298
   223
      //FIXME error
athos@1298
   224
    }
athos@1298
   225
    int b=lpx_get_row_type(lp, i);
athos@1298
   226
    double lo=lpx_get_row_lb(lp, i);
athos@1298
   227
    if (up==INF) {
athos@1298
   228
      switch (b) {
athos@1298
   229
      case LPX_FR:
athos@1298
   230
      case LPX_LO:
athos@1298
   231
	break;
athos@1298
   232
      case LPX_UP:
athos@1298
   233
	lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
athos@1298
   234
	break;
athos@1298
   235
      case LPX_DB:
athos@1298
   236
      case LPX_FX:
athos@1298
   237
	lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
athos@1298
   238
	break;
athos@1298
   239
      default: ;
athos@1261
   240
	//FIXME error
athos@1261
   241
      }
athos@1298
   242
    } else {
athos@1298
   243
      switch (b) {
athos@1298
   244
      case LPX_FR:
athos@1298
   245
	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
athos@1298
   246
	break;
athos@1298
   247
      case LPX_UP:
athos@1298
   248
	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
athos@1298
   249
	break;
athos@1298
   250
      case LPX_LO:
athos@1298
   251
      case LPX_DB:
athos@1298
   252
      case LPX_FX:
athos@1298
   253
	if (lo==up) 
athos@1298
   254
	  lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
athos@1298
   255
	else 
athos@1298
   256
	  lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
athos@1298
   257
	break;
athos@1298
   258
      default: ;
athos@1298
   259
	//FIXME error
athos@1261
   260
      }
athos@1261
   261
    }
athos@1298
   262
  }
athos@1379
   263
athos@1379
   264
  void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
athos@1379
   265
  {
athos@1379
   266
    //Bad parameter
athos@1379
   267
    if (lb==INF || ub==-INF) {
athos@1379
   268
      //FIXME error
athos@1379
   269
    }
athos@1379
   270
athos@1379
   271
    if (lb == -INF){
athos@1379
   272
      if (ub == INF){
athos@1379
   273
	lpx_set_row_bnds(lp, i, LPX_FR, lb, ub);
athos@1379
   274
      }
athos@1379
   275
      else{
athos@1379
   276
	lpx_set_row_bnds(lp, i, LPX_UP, lb, ub);
athos@1379
   277
      }
athos@1379
   278
    }
athos@1379
   279
    else{
athos@1379
   280
      if (ub==INF){
athos@1379
   281
	lpx_set_row_bnds(lp, i, LPX_LO, lb, ub);
athos@1379
   282
athos@1379
   283
      }
athos@1379
   284
      else{
athos@1379
   285
	if (lb == ub){
athos@1379
   286
	  lpx_set_row_bnds(lp, i, LPX_FX, lb, ub);
athos@1379
   287
	}
athos@1379
   288
	else{
athos@1379
   289
	  lpx_set_row_bnds(lp, i, LPX_DB, lb, ub);
athos@1379
   290
	}
athos@1379
   291
      }
athos@1379
   292
    }
athos@1379
   293
athos@1379
   294
  }
athos@1261
   295
  
athos@1298
   296
  void LpGlpk::_setObjCoeff(int i, Value obj_coef)
athos@1298
   297
  {
athos@1376
   298
    //i=0 means the constant term (shift)
athos@1298
   299
    lpx_set_obj_coef(lp, i, obj_coef);
athos@1298
   300
  }
athos@1261
   301
athos@1377
   302
  void LpGlpk::_clearObj()
athos@1376
   303
  {
athos@1377
   304
    for (int i=0;i<=lpx_get_num_cols(lp);++i){
athos@1377
   305
      lpx_set_obj_coef(lp, i, 0);
athos@1376
   306
    }
athos@1376
   307
  }
athos@1377
   308
//   void LpGlpk::_setObj(int length,
athos@1377
   309
// 		       int  const * indices, 
athos@1377
   310
// 		       Value  const * values )
athos@1377
   311
//   {
athos@1377
   312
//     Value new_values[1+lpx_num_cols()];
athos@1377
   313
//     for (i=0;i<=lpx_num_cols();++i){
athos@1377
   314
//       new_values[i]=0;
athos@1377
   315
//     }
athos@1377
   316
//     for (i=1;i<=length;++i){
athos@1377
   317
//       new_values[indices[i]]=values[i];
athos@1377
   318
//     }
athos@1377
   319
    
athos@1377
   320
//     for (i=0;i<=lpx_num_cols();++i){
athos@1377
   321
//       lpx_set_obj_coef(lp, i, new_values[i]);
athos@1377
   322
//     }
athos@1377
   323
//   }
alpar@1263
   324
alpar@1303
   325
  LpGlpk::SolveExitStatus LpGlpk::_solve()
alpar@1263
   326
  {
athos@1298
   327
    int i=  lpx_simplex(lp);
athos@1298
   328
    switch (i) {
athos@1298
   329
    case LPX_E_OK: 
athos@1298
   330
      return SOLVED;
athos@1298
   331
      break;
athos@1298
   332
    default:
athos@1298
   333
      return UNSOLVED;
athos@1298
   334
    }
alpar@1263
   335
  }
alpar@1263
   336
alpar@1293
   337
  LpGlpk::Value LpGlpk::_getPrimal(int i)
alpar@1263
   338
  {
athos@1298
   339
    return lpx_get_col_prim(lp,i);
alpar@1263
   340
  }
alpar@1263
   341
  
alpar@1312
   342
  LpGlpk::Value LpGlpk::_getPrimalValue()
alpar@1312
   343
  {
athos@1314
   344
    return lpx_get_obj_val(lp);
alpar@1312
   345
  }
alpar@1312
   346
  
athos@1298
   347
 
alpar@1312
   348
  LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
alpar@1294
   349
  {
athos@1298
   350
    int stat=  lpx_get_status(lp);
athos@1298
   351
    switch (stat) {
athos@1298
   352
    case LPX_UNDEF://Undefined (no solve has been run yet)
athos@1298
   353
      return UNDEFINED;
athos@1298
   354
      break;
athos@1298
   355
    case LPX_NOFEAS://There is no feasible solution (primal, I guess)
athos@1298
   356
    case LPX_INFEAS://Infeasible 
athos@1298
   357
      return INFEASIBLE;
athos@1298
   358
      break;
athos@1298
   359
    case LPX_UNBND://Unbounded
athos@1298
   360
      return INFINITE;
athos@1298
   361
      break;
athos@1298
   362
    case LPX_FEAS://Feasible
alpar@1300
   363
      return FEASIBLE;
athos@1298
   364
      break;
athos@1298
   365
    case LPX_OPT://Feasible
athos@1298
   366
      return OPTIMAL;
athos@1298
   367
      break;
alpar@1300
   368
    default:
alpar@1300
   369
      return UNDEFINED; //to avoid gcc warning
athos@1298
   370
      //FIXME error
athos@1298
   371
    }
alpar@1294
   372
  }
alpar@1263
   373
alpar@1263
   374
alpar@1312
   375
  void LpGlpk::_setMax()
alpar@1312
   376
  {
alpar@1321
   377
    lpx_set_obj_dir(lp, LPX_MAX);
alpar@1321
   378
  }
alpar@1321
   379
alpar@1312
   380
  void LpGlpk::_setMin()
alpar@1312
   381
  {
alpar@1321
   382
    lpx_set_obj_dir(lp, LPX_MIN);
alpar@1321
   383
  }
alpar@1321
   384
alpar@1321
   385
 
alpar@1321
   386
  void LpGlpk::messageLevel(int m)
alpar@1321
   387
  {
alpar@1321
   388
    lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
alpar@1321
   389
  }
alpar@1312
   390
alpar@1326
   391
  void LpGlpk::presolver(bool b)
alpar@1326
   392
  {
alpar@1326
   393
    lpx_set_int_parm(lp, LPX_K_PRESOL, b);
alpar@1326
   394
  }
alpar@1326
   395
alpar@1312
   396
 
athos@1261
   397
} //END OF NAMESPACE LEMON
athos@1261
   398
athos@1261
   399
#endif //LEMON_LP_GLPK_CC