src/lemon/lp_glpk.cc
author alpar
Mon, 18 Apr 2005 14:18:12 +0000
changeset 1366 d00b85f8be45
parent 1359 1581f961cfaa
child 1368 f9d0d792c8a6
permissions -rw-r--r--
gcc-3.4 compile fix
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@1364
    33
    return *((LpSolverBase *)0);
alpar@1364
    34
  }
alpar@1364
    35
  
alpar@1364
    36
  ///\e
alpar@1364
    37
alpar@1364
    38
  ///\bug Unimplemented!
alpar@1364
    39
  ///
alpar@1364
    40
  LpSolverBase &LpGlpk::_copyLp()
alpar@1364
    41
  {
alpar@1364
    42
    return *((LpSolverBase *)0);
alpar@1364
    43
  }
alpar@1364
    44
alpar@1321
    45
  LpGlpk::LpGlpk() : Parent(), 
alpar@1321
    46
		     lp(lpx_create_prob()) {
alpar@1321
    47
    ///\todo constrol function for this:
alpar@1321
    48
    lpx_set_int_parm(lp, LPX_K_DUAL, 1);
alpar@1321
    49
    messageLevel(0);
alpar@1321
    50
  }
alpar@1321
    51
  
alpar@1321
    52
  LpGlpk::~LpGlpk() {
alpar@1321
    53
    lpx_delete_prob(lp);
alpar@1321
    54
  }
alpar@1321
    55
  
alpar@1321
    56
  int LpGlpk::_addCol() { 
alpar@1321
    57
    int i=lpx_add_cols(lp, 1);
alpar@1321
    58
    _setColLowerBound(i, -INF);
alpar@1321
    59
    _setColUpperBound(i, INF);
alpar@1321
    60
    return i;
alpar@1321
    61
  }
alpar@1321
    62
alpar@1321
    63
  int LpGlpk::_addRow() { 
alpar@1321
    64
    int i=lpx_add_rows(lp, 1);
alpar@1321
    65
    return i;
alpar@1321
    66
  }
alpar@1321
    67
alpar@1321
    68
  
alpar@1321
    69
  void LpGlpk::_setRowCoeffs(int i, 
alpar@1321
    70
			     int length,
alpar@1321
    71
			     const int   * indices, 
alpar@1321
    72
			     const Value   * values )
alpar@1321
    73
  {
alpar@1321
    74
    lpx_set_mat_row(lp, i, length,
alpar@1321
    75
		    const_cast<int * >(indices) ,
alpar@1321
    76
		    const_cast<Value * >(values));
alpar@1321
    77
  }
alpar@1321
    78
  
alpar@1321
    79
  void LpGlpk::_setColCoeffs(int i, 
alpar@1321
    80
			     int length,
alpar@1321
    81
			     const int   * indices, 
alpar@1321
    82
			     const Value   * values)
alpar@1321
    83
  {
alpar@1321
    84
    lpx_set_mat_col(lp, i, length,
alpar@1321
    85
		    const_cast<int * >(indices),
alpar@1321
    86
		    const_cast<Value * >(values));
alpar@1321
    87
  }
alpar@1321
    88
  
alpar@1321
    89
  void LpGlpk::_setColLowerBound(int i, Value lo)
alpar@1321
    90
  {
alpar@1321
    91
    if (lo==INF) {
alpar@1321
    92
      //FIXME error
alpar@1321
    93
    }
alpar@1321
    94
    int b=lpx_get_col_type(lp, i);
alpar@1321
    95
    double up=lpx_get_col_ub(lp, i);	
alpar@1321
    96
    if (lo==-INF) {
alpar@1321
    97
      switch (b) {
alpar@1321
    98
      case LPX_FR:
alpar@1321
    99
      case LPX_LO:
alpar@1321
   100
	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
alpar@1321
   101
	break;
alpar@1321
   102
      case LPX_UP:
alpar@1321
   103
	break;
alpar@1321
   104
      case LPX_DB:
alpar@1321
   105
      case LPX_FX:
alpar@1321
   106
	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
alpar@1321
   107
	break;
alpar@1321
   108
      default: ;
alpar@1321
   109
	//FIXME error
alpar@1321
   110
      }
alpar@1321
   111
    } else {
alpar@1321
   112
      switch (b) {
alpar@1321
   113
      case LPX_FR:
alpar@1321
   114
      case LPX_LO:
alpar@1321
   115
	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
alpar@1321
   116
	break;
alpar@1321
   117
      case LPX_UP:	  
alpar@1321
   118
      case LPX_DB:
alpar@1321
   119
      case LPX_FX:
alpar@1321
   120
	if (lo==up) 
alpar@1321
   121
	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
alpar@1321
   122
	else 
alpar@1321
   123
	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
alpar@1321
   124
	break;
alpar@1321
   125
      default: ;
alpar@1321
   126
	//FIXME error
alpar@1321
   127
      }
athos@1261
   128
    }
athos@1261
   129
alpar@1321
   130
  }
alpar@1321
   131
  
alpar@1321
   132
  void LpGlpk::_setColUpperBound(int i, Value up)
alpar@1321
   133
  {
alpar@1321
   134
    if (up==-INF) {
alpar@1321
   135
      //FIXME error
athos@1261
   136
    }
alpar@1321
   137
    int b=lpx_get_col_type(lp, i);
alpar@1321
   138
    double lo=lpx_get_col_lb(lp, i);
alpar@1321
   139
    if (up==INF) {
alpar@1321
   140
      switch (b) {
alpar@1321
   141
      case LPX_FR:
alpar@1321
   142
      case LPX_LO:
alpar@1321
   143
	break;
alpar@1321
   144
      case LPX_UP:
alpar@1321
   145
	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
alpar@1321
   146
	break;
alpar@1321
   147
      case LPX_DB:
alpar@1321
   148
      case LPX_FX:
alpar@1321
   149
	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
alpar@1321
   150
	break;
alpar@1321
   151
      default: ;
athos@1261
   152
	//FIXME error
athos@1261
   153
      }
alpar@1321
   154
    } else {
alpar@1321
   155
      switch (b) {
alpar@1321
   156
      case LPX_FR:
alpar@1321
   157
	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
alpar@1321
   158
	break;
alpar@1321
   159
      case LPX_UP:
alpar@1321
   160
	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
alpar@1321
   161
	break;
alpar@1321
   162
      case LPX_LO:
alpar@1321
   163
      case LPX_DB:
alpar@1321
   164
      case LPX_FX:
alpar@1321
   165
	if (lo==up) 
alpar@1321
   166
	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
alpar@1321
   167
	else 
alpar@1321
   168
	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
alpar@1321
   169
	break;
alpar@1321
   170
      default: ;
athos@1261
   171
	//FIXME error
athos@1261
   172
      }
alpar@1321
   173
    }
alpar@1321
   174
  }
alpar@1321
   175
  
alpar@1321
   176
  void LpGlpk::_setRowLowerBound(int i, Value lo)
alpar@1321
   177
  {
alpar@1321
   178
    if (lo==INF) {
alpar@1321
   179
      //FIXME error
alpar@1321
   180
    }
alpar@1321
   181
    int b=lpx_get_row_type(lp, i);
alpar@1321
   182
    double up=lpx_get_row_ub(lp, i);	
alpar@1321
   183
    if (lo==-INF) {
alpar@1321
   184
      switch (b) {
alpar@1321
   185
      case LPX_FR:
alpar@1321
   186
      case LPX_LO:
alpar@1321
   187
	lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
alpar@1321
   188
	break;
alpar@1321
   189
      case LPX_UP:
alpar@1321
   190
	break;
alpar@1321
   191
      case LPX_DB:
alpar@1321
   192
      case LPX_FX:
alpar@1321
   193
	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
alpar@1321
   194
	break;
alpar@1321
   195
      default: ;
alpar@1321
   196
	//FIXME error
alpar@1321
   197
      }
alpar@1321
   198
    } else {
alpar@1321
   199
      switch (b) {
alpar@1321
   200
      case LPX_FR:
alpar@1321
   201
      case LPX_LO:
alpar@1321
   202
	lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
alpar@1321
   203
	break;
alpar@1321
   204
      case LPX_UP:	  
alpar@1321
   205
      case LPX_DB:
alpar@1321
   206
      case LPX_FX:
alpar@1321
   207
	if (lo==up) 
alpar@1321
   208
	  lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
alpar@1321
   209
	else 
alpar@1321
   210
	  lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
alpar@1321
   211
	break;
alpar@1321
   212
      default: ;
alpar@1321
   213
	//FIXME error
athos@1261
   214
      }
athos@1261
   215
    }
alpar@1321
   216
  }
athos@1261
   217
  
athos@1298
   218
  void LpGlpk::_setRowUpperBound(int i, Value up)
athos@1298
   219
  {
athos@1298
   220
    if (up==-INF) {
athos@1298
   221
      //FIXME error
athos@1298
   222
    }
athos@1298
   223
    int b=lpx_get_row_type(lp, i);
athos@1298
   224
    double lo=lpx_get_row_lb(lp, i);
athos@1298
   225
    if (up==INF) {
athos@1298
   226
      switch (b) {
athos@1298
   227
      case LPX_FR:
athos@1298
   228
      case LPX_LO:
athos@1298
   229
	break;
athos@1298
   230
      case LPX_UP:
athos@1298
   231
	lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
athos@1298
   232
	break;
athos@1298
   233
      case LPX_DB:
athos@1298
   234
      case LPX_FX:
athos@1298
   235
	lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
athos@1298
   236
	break;
athos@1298
   237
      default: ;
athos@1261
   238
	//FIXME error
athos@1261
   239
      }
athos@1298
   240
    } else {
athos@1298
   241
      switch (b) {
athos@1298
   242
      case LPX_FR:
athos@1298
   243
	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
athos@1298
   244
	break;
athos@1298
   245
      case LPX_UP:
athos@1298
   246
	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
athos@1298
   247
	break;
athos@1298
   248
      case LPX_LO:
athos@1298
   249
      case LPX_DB:
athos@1298
   250
      case LPX_FX:
athos@1298
   251
	if (lo==up) 
athos@1298
   252
	  lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
athos@1298
   253
	else 
athos@1298
   254
	  lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
athos@1298
   255
	break;
athos@1298
   256
      default: ;
athos@1298
   257
	//FIXME error
athos@1261
   258
      }
athos@1261
   259
    }
athos@1298
   260
  }
athos@1261
   261
  
athos@1298
   262
  void LpGlpk::_setObjCoeff(int i, Value obj_coef)
athos@1298
   263
  {
athos@1298
   264
    lpx_set_obj_coef(lp, i, obj_coef);
athos@1298
   265
  }
athos@1261
   266
alpar@1263
   267
alpar@1303
   268
  LpGlpk::SolveExitStatus LpGlpk::_solve()
alpar@1263
   269
  {
athos@1298
   270
    int i=  lpx_simplex(lp);
athos@1298
   271
    switch (i) {
athos@1298
   272
    case LPX_E_OK: 
athos@1298
   273
      return SOLVED;
athos@1298
   274
      break;
athos@1298
   275
    default:
athos@1298
   276
      return UNSOLVED;
athos@1298
   277
    }
alpar@1263
   278
  }
alpar@1263
   279
alpar@1293
   280
  LpGlpk::Value LpGlpk::_getPrimal(int i)
alpar@1263
   281
  {
athos@1298
   282
    return lpx_get_col_prim(lp,i);
alpar@1263
   283
  }
alpar@1263
   284
  
alpar@1312
   285
  LpGlpk::Value LpGlpk::_getPrimalValue()
alpar@1312
   286
  {
athos@1314
   287
    return lpx_get_obj_val(lp);
alpar@1312
   288
  }
alpar@1312
   289
  
athos@1298
   290
 
alpar@1312
   291
  LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
alpar@1294
   292
  {
athos@1298
   293
    int stat=  lpx_get_status(lp);
athos@1298
   294
    switch (stat) {
athos@1298
   295
    case LPX_UNDEF://Undefined (no solve has been run yet)
athos@1298
   296
      return UNDEFINED;
athos@1298
   297
      break;
athos@1298
   298
    case LPX_NOFEAS://There is no feasible solution (primal, I guess)
athos@1298
   299
    case LPX_INFEAS://Infeasible 
athos@1298
   300
      return INFEASIBLE;
athos@1298
   301
      break;
athos@1298
   302
    case LPX_UNBND://Unbounded
athos@1298
   303
      return INFINITE;
athos@1298
   304
      break;
athos@1298
   305
    case LPX_FEAS://Feasible
alpar@1300
   306
      return FEASIBLE;
athos@1298
   307
      break;
athos@1298
   308
    case LPX_OPT://Feasible
athos@1298
   309
      return OPTIMAL;
athos@1298
   310
      break;
alpar@1300
   311
    default:
alpar@1300
   312
      return UNDEFINED; //to avoid gcc warning
athos@1298
   313
      //FIXME error
athos@1298
   314
    }
alpar@1294
   315
  }
alpar@1263
   316
alpar@1263
   317
alpar@1312
   318
  void LpGlpk::_setMax()
alpar@1312
   319
  {
alpar@1321
   320
    lpx_set_obj_dir(lp, LPX_MAX);
alpar@1321
   321
  }
alpar@1321
   322
alpar@1312
   323
  void LpGlpk::_setMin()
alpar@1312
   324
  {
alpar@1321
   325
    lpx_set_obj_dir(lp, LPX_MIN);
alpar@1321
   326
  }
alpar@1321
   327
alpar@1321
   328
 
alpar@1321
   329
  void LpGlpk::messageLevel(int m)
alpar@1321
   330
  {
alpar@1321
   331
    lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
alpar@1321
   332
  }
alpar@1312
   333
alpar@1326
   334
  void LpGlpk::presolver(bool b)
alpar@1326
   335
  {
alpar@1326
   336
    lpx_set_int_parm(lp, LPX_K_PRESOL, b);
alpar@1326
   337
  }
alpar@1326
   338
alpar@1312
   339
 
athos@1261
   340
} //END OF NAMESPACE LEMON
athos@1261
   341
athos@1261
   342
#endif //LEMON_LP_GLPK_CC