lemon/lp_glpk.cc
author deba
Tue, 22 Jul 2008 11:20:06 +0000
changeset 2616 02971275e7bf
parent 2591 3b4d5bc3b4fb
child 2622 fa2877651022
permissions -rw-r--r--
Back port bug fix from hg changeset [0915721396dc]
athos@1261
     1
/* -*- C++ -*-
athos@1261
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
athos@1261
     8
 *
athos@1261
     9
 * Permission to use, modify and distribute this software is granted
athos@1261
    10
 * provided that this copyright notice appears in all copies. For
athos@1261
    11
 * precise terms see the accompanying LICENSE file.
athos@1261
    12
 *
athos@1261
    13
 * This software is provided "AS IS" with no warranty of any kind,
athos@1261
    14
 * express or implied, and with no claim as to its suitability for any
athos@1261
    15
 * purpose.
athos@1261
    16
 *
athos@1261
    17
 */
athos@1261
    18
athos@1261
    19
///\file
athos@1261
    20
///\brief Implementation of the LEMON-GLPK lp solver interface.
athos@1261
    21
ladanyi@1305
    22
#include <lemon/lp_glpk.h>
athos@1473
    23
//#include <iostream>
deba@2441
    24
deba@2441
    25
#if GLP_MAJOR_VERSION > 4 || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION > 15)
deba@2441
    26
#define LEMON_glp(func) (glp_##func)
deba@2441
    27
#define LEMON_lpx(func) (lpx_##func)
deba@2441
    28
deba@2441
    29
#define LEMON_GLP(def) (GLP_##def)
deba@2441
    30
#define LEMON_LPX(def) (LPX_##def)
deba@2441
    31
deba@2441
    32
#else
deba@2441
    33
deba@2441
    34
#define LEMON_glp(func) (lpx_##func)
deba@2441
    35
#define LEMON_lpx(func) (lpx_##func)
deba@2441
    36
deba@2441
    37
#define LEMON_GLP(def) (LPX_##def)
deba@2441
    38
#define LEMON_LPX(def) (LPX_##def)
deba@2441
    39
deba@2441
    40
#endif
deba@2441
    41
athos@1261
    42
namespace lemon {
athos@1261
    43
deba@2363
    44
  LpGlpk::LpGlpk() : Parent() {
deba@2441
    45
    solved = false;
deba@2363
    46
    rows = _lp_bits::LpId(1);
deba@2363
    47
    cols = _lp_bits::LpId(1);
deba@2441
    48
    lp = LEMON_glp(create_prob)();
deba@2441
    49
    LEMON_glp(create_index)(lp);
deba@2441
    50
    LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_DUAL), 1);
alpar@1321
    51
    messageLevel(0);
alpar@1321
    52
  }
alpar@1321
    53
  
deba@2363
    54
  LpGlpk::LpGlpk(const LpGlpk &glp) : Parent() {
deba@2441
    55
    solved = false;
deba@2363
    56
    rows = _lp_bits::LpId(1);
deba@2363
    57
    cols = _lp_bits::LpId(1);
deba@2441
    58
    lp = LEMON_glp(create_prob)();
deba@2441
    59
    LEMON_glp(create_index)(lp);
deba@2363
    60
    ///\todo control function for this:
deba@2441
    61
    LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_DUAL), 1);
alpar@2321
    62
    messageLevel(0);
alpar@2321
    63
    //Coefficient matrix, row bounds
deba@2441
    64
    LEMON_glp(add_rows)(lp, LEMON_glp(get_num_rows)(glp.lp));
deba@2441
    65
    LEMON_glp(add_cols)(lp, LEMON_glp(get_num_cols)(glp.lp));
alpar@2321
    66
    int len;
ladanyi@2591
    67
    std::vector<int> ind(1+LEMON_glp(get_num_cols)(glp.lp));
ladanyi@2591
    68
    std::vector<Value> val(1+LEMON_glp(get_num_cols)(glp.lp));
deba@2441
    69
    for (int i=1;i<=LEMON_glp(get_num_rows)(glp.lp);++i)
alpar@2321
    70
      {
ladanyi@2591
    71
	len=LEMON_glp(get_mat_row)(glp.lp,i,&*ind.begin(),&*val.begin());
ladanyi@2591
    72
	LEMON_glp(set_mat_row)(lp, i,len,&*ind.begin(),&*val.begin());
deba@2441
    73
	LEMON_glp(set_row_bnds)(lp,i,
deba@2441
    74
				LEMON_glp(get_row_type)(glp.lp,i),
deba@2441
    75
				LEMON_glp(get_row_lb)(glp.lp,i),
deba@2441
    76
				LEMON_glp(get_row_ub)(glp.lp,i));
alpar@2321
    77
      }
alpar@2321
    78
alpar@2321
    79
    //Objective function, coloumn bounds
deba@2441
    80
    LEMON_glp(set_obj_dir)(lp, LEMON_glp(get_obj_dir)(glp.lp));
alpar@2321
    81
    //Objectif function's constant term treated separately
deba@2441
    82
    LEMON_glp(set_obj_coef)(lp,0,LEMON_glp(get_obj_coef)(glp.lp,0));
deba@2441
    83
    for (int i=1;i<=LEMON_glp(get_num_cols)(glp.lp);++i)
alpar@2321
    84
      {
deba@2441
    85
	LEMON_glp(set_obj_coef)(lp,i,
deba@2441
    86
				LEMON_glp(get_obj_coef)(glp.lp,i));
deba@2441
    87
	LEMON_glp(set_col_bnds)(lp,i,
deba@2441
    88
				LEMON_glp(get_col_type)(glp.lp,i),
deba@2441
    89
				LEMON_glp(get_col_lb)(glp.lp,i),
deba@2441
    90
				LEMON_glp(get_col_ub)(glp.lp,i));
alpar@2321
    91
      }
deba@2605
    92
    rows = glp.rows;
deba@2605
    93
    cols = glp.cols;
alpar@2321
    94
  }
alpar@2321
    95
  
alpar@1321
    96
  LpGlpk::~LpGlpk() {
deba@2441
    97
    LEMON_glp(delete_prob)(lp);
alpar@1321
    98
  }
alpar@1321
    99
  
alpar@1321
   100
  int LpGlpk::_addCol() { 
deba@2441
   101
    int i=LEMON_glp(add_cols)(lp, 1);
deba@2441
   102
    LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), 0.0, 0.0);
deba@2441
   103
    solved = false;
alpar@1321
   104
    return i;
alpar@1321
   105
  }
alpar@1321
   106
athos@1436
   107
  ///\e
athos@1436
   108
athos@1436
   109
deba@2605
   110
  LpSolverBase* LpGlpk::_newLp()
athos@1436
   111
  {
deba@2605
   112
    LpGlpk* newlp = new LpGlpk;
deba@2605
   113
    return newlp;
athos@1436
   114
  }
athos@1436
   115
  
athos@1436
   116
  ///\e
athos@1436
   117
deba@2605
   118
  LpSolverBase* LpGlpk::_copyLp()
athos@1436
   119
  {
deba@2605
   120
    LpGlpk *newlp = new LpGlpk(*this);
deba@2605
   121
    return newlp;
athos@1436
   122
  }
athos@1436
   123
alpar@1321
   124
  int LpGlpk::_addRow() { 
deba@2441
   125
    int i=LEMON_glp(add_rows)(lp, 1);
deba@2441
   126
    solved = false;
alpar@1321
   127
    return i;
alpar@1321
   128
  }
alpar@1321
   129
alpar@1321
   130
  
athos@1432
   131
  void LpGlpk::_eraseCol(int i) {
deba@2386
   132
    int ca[2];
deba@2386
   133
    ca[1]=i;
deba@2441
   134
    LEMON_glp(del_cols)(lp, 1, ca);
deba@2441
   135
    solved = false;
athos@1432
   136
  }
athos@1432
   137
  
athos@1432
   138
  void LpGlpk::_eraseRow(int i) {
deba@2386
   139
    int ra[2];
deba@2386
   140
    ra[1]=i;
deba@2441
   141
    LEMON_glp(del_rows)(lp, 1, ra);
deba@2441
   142
    solved = false;
athos@1432
   143
  }
athos@1432
   144
deba@2386
   145
  void LpGlpk::_getColName(int c, std::string & name) const
alpar@1895
   146
  {
alpar@1895
   147
    
deba@2441
   148
    const char *n = LEMON_glp(get_col_name)(lp,c);
alpar@1895
   149
    name = n?n:"";
alpar@1895
   150
  }
alpar@1895
   151
  
alpar@1895
   152
  
deba@2386
   153
  void LpGlpk::_setColName(int c, const std::string & name)
alpar@1895
   154
  {
deba@2441
   155
    LEMON_glp(set_col_name)(lp,c,const_cast<char*>(name.c_str()));
athos@2349
   156
alpar@1895
   157
  }
deba@2366
   158
deba@2366
   159
  int LpGlpk::_colByName(const std::string& name) const
deba@2366
   160
  {
deba@2441
   161
    int k = LEMON_glp(find_col)(lp, const_cast<char*>(name.c_str()));
deba@2366
   162
    return k > 0 ? k : -1; 
deba@2366
   163
  }
deba@2366
   164
alpar@1895
   165
  
deba@2364
   166
  void LpGlpk::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e) 
alpar@1321
   167
  {
deba@2312
   168
    std::vector<int> indices;
deba@2312
   169
    std::vector<Value> values;
deba@2312
   170
deba@2312
   171
    indices.push_back(0);
deba@2312
   172
    values.push_back(0);
deba@2312
   173
deba@2364
   174
    for(ConstRowIterator it=b; it!=e; ++it) {
deba@2312
   175
      indices.push_back(it->first);
deba@2312
   176
      values.push_back(it->second);
deba@2312
   177
    }
deba@2312
   178
deba@2441
   179
    LEMON_glp(set_mat_row)(lp, i, values.size() - 1, 
deba@2441
   180
				&indices[0], &values[0]);
deba@2441
   181
deba@2441
   182
    solved = false;
alpar@1321
   183
  }
deba@2364
   184
deba@2386
   185
  void LpGlpk::_getRowCoeffs(int ix, RowIterator b) const
deba@2364
   186
  {
deba@2441
   187
    int length = LEMON_glp(get_mat_row)(lp, ix, 0, 0);
deba@2364
   188
    
deba@2364
   189
    std::vector<int> indices(length + 1);
deba@2364
   190
    std::vector<Value> values(length + 1);
deba@2364
   191
    
deba@2441
   192
    LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
deba@2364
   193
    
deba@2364
   194
    for (int i = 1; i <= length; ++i) {
deba@2364
   195
      *b = std::make_pair(indices[i], values[i]);
deba@2364
   196
      ++b;
deba@2364
   197
    }
deba@2364
   198
  }
alpar@1321
   199
  
deba@2386
   200
  void LpGlpk::_setColCoeffs(int ix, ConstColIterator b, ConstColIterator e) {
deba@2312
   201
deba@2312
   202
    std::vector<int> indices;
deba@2312
   203
    std::vector<Value> values;
deba@2312
   204
deba@2312
   205
    indices.push_back(0);
deba@2312
   206
    values.push_back(0);
deba@2312
   207
deba@2364
   208
    for(ConstColIterator it=b; it!=e; ++it) {
deba@2312
   209
      indices.push_back(it->first);
deba@2312
   210
      values.push_back(it->second);
deba@2312
   211
    }
deba@2312
   212
    
deba@2441
   213
    LEMON_glp(set_mat_col)(lp, ix, values.size() - 1, 
deba@2441
   214
				&indices[0], &values[0]);
deba@2441
   215
deba@2441
   216
    solved = false;
alpar@1321
   217
  }
athos@1431
   218
deba@2386
   219
  void LpGlpk::_getColCoeffs(int ix, ColIterator b) const
deba@2364
   220
  {
deba@2441
   221
    int length = LEMON_glp(get_mat_col)(lp, ix, 0, 0);
deba@2364
   222
    
deba@2364
   223
    std::vector<int> indices(length + 1);
deba@2364
   224
    std::vector<Value> values(length + 1);
deba@2364
   225
    
deba@2441
   226
    LEMON_glp(get_mat_col)(lp, ix, &indices[0], &values[0]);
deba@2364
   227
    
deba@2364
   228
    for (int i = 1; i <= length; ++i) {
deba@2364
   229
      *b = std::make_pair(indices[i], values[i]);
deba@2364
   230
      ++b;
deba@2364
   231
    }
deba@2364
   232
  }
athos@1431
   233
deba@2386
   234
  void LpGlpk::_setCoeff(int ix, int jx, Value value) 
athos@1431
   235
  {
deba@2312
   236
deba@2441
   237
    if (LEMON_glp(get_num_cols)(lp) < LEMON_glp(get_num_rows)(lp)) {
deba@2312
   238
deba@2441
   239
      int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0);
deba@2312
   240
      
deba@2312
   241
      std::vector<int> indices(length + 2);
deba@2312
   242
      std::vector<Value> values(length + 2);
deba@2312
   243
      
deba@2441
   244
      LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
deba@2312
   245
      
deba@2312
   246
      //The following code does not suppose that the elements of the
deba@2312
   247
      //array indices are sorted
deba@2312
   248
      bool found=false;
deba@2312
   249
      for (int i = 1; i <= length; ++i) {
deba@2386
   250
        if (indices[i]==jx){
deba@2312
   251
          found=true;
deba@2312
   252
          values[i]=value;
deba@2312
   253
          break;
deba@2312
   254
        }
deba@2312
   255
      }
deba@2312
   256
      if (!found){
deba@2312
   257
        ++length;
deba@2386
   258
        indices[length]=jx;
deba@2312
   259
        values[length]=value;
deba@2312
   260
      }
athos@1431
   261
    
deba@2441
   262
      LEMON_glp(set_mat_row)(lp, ix, length, &indices[0], &values[0]);
deba@2312
   263
deba@2312
   264
    } else {
deba@2312
   265
deba@2441
   266
      int length=LEMON_glp(get_mat_col)(lp, jx, 0, 0);
deba@2312
   267
      
deba@2312
   268
      std::vector<int> indices(length + 2);
deba@2312
   269
      std::vector<Value> values(length + 2);
deba@2312
   270
      
deba@2441
   271
      LEMON_glp(get_mat_col)(lp, jx, &indices[0], &values[0]);
deba@2312
   272
      
deba@2312
   273
      //The following code does not suppose that the elements of the
deba@2312
   274
      //array indices are sorted
deba@2312
   275
      bool found=false;
deba@2312
   276
      for (int i = 1; i <= length; ++i) {
deba@2386
   277
        if (indices[i]==jx){
deba@2312
   278
          found=true;
deba@2312
   279
          values[i]=value;
deba@2312
   280
          break;
deba@2312
   281
        }
deba@2312
   282
      }
deba@2312
   283
      if (!found){
deba@2312
   284
        ++length;
deba@2386
   285
        indices[length]=ix;
deba@2312
   286
        values[length]=value;
deba@2312
   287
      }
athos@1431
   288
    
deba@2441
   289
      LEMON_glp(set_mat_col)(lp, jx, length, &indices[0], &values[0]);
athos@1431
   290
    }
deba@2441
   291
deba@2441
   292
    solved = false;
athos@1431
   293
  }
athos@1431
   294
deba@2386
   295
  LpGlpk::Value LpGlpk::_getCoeff(int ix, int jx) const
athos@2324
   296
  {
athos@2328
   297
deba@2441
   298
    int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0);
athos@2328
   299
    
deba@2364
   300
    std::vector<int> indices(length + 1);
deba@2364
   301
    std::vector<Value> values(length + 1);
athos@2328
   302
    
deba@2441
   303
    LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
athos@2328
   304
    
athos@2328
   305
    //The following code does not suppose that the elements of the
athos@2328
   306
    //array indices are sorted
athos@2328
   307
    for (int i = 1; i <= length; ++i) {
deba@2386
   308
      if (indices[i]==jx){
athos@2328
   309
	return values[i];
athos@2328
   310
      }
athos@2328
   311
    }
athos@2324
   312
    return 0;
athos@2328
   313
athos@2324
   314
  }
athos@2324
   315
athos@2324
   316
alpar@1321
   317
  void LpGlpk::_setColLowerBound(int i, Value lo)
alpar@1321
   318
  {
alpar@1321
   319
    if (lo==INF) {
alpar@1321
   320
      //FIXME error
alpar@1321
   321
    }
deba@2441
   322
    int b=LEMON_glp(get_col_type)(lp, i);
deba@2441
   323
    double up=LEMON_glp(get_col_ub)(lp, i);	
alpar@1321
   324
    if (lo==-INF) {
alpar@1321
   325
      switch (b) {
deba@2441
   326
      case LEMON_GLP(FR):
deba@2441
   327
      case LEMON_GLP(LO):
deba@2441
   328
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up);
alpar@1321
   329
	break;
deba@2441
   330
      case LEMON_GLP(UP):
alpar@1321
   331
	break;
deba@2441
   332
      case LEMON_GLP(DB):
deba@2441
   333
      case LEMON_GLP(FX):
deba@2441
   334
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
alpar@1321
   335
	break;
alpar@1321
   336
      default: ;
alpar@1321
   337
	//FIXME error
alpar@1321
   338
      }
alpar@1321
   339
    } else {
alpar@1321
   340
      switch (b) {
deba@2441
   341
      case LEMON_GLP(FR):
deba@2441
   342
      case LEMON_GLP(LO):
deba@2441
   343
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up);
alpar@1321
   344
	break;
deba@2441
   345
      case LEMON_GLP(UP):	  
deba@2441
   346
      case LEMON_GLP(DB):
deba@2441
   347
      case LEMON_GLP(FX):
alpar@1321
   348
	if (lo==up) 
deba@2441
   349
	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up);
alpar@1321
   350
	else 
deba@2441
   351
	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up);
alpar@1321
   352
	break;
alpar@1321
   353
      default: ;
alpar@1321
   354
	//FIXME error
alpar@1321
   355
      }
athos@1261
   356
    }
athos@1261
   357
deba@2441
   358
    solved = false;
alpar@1321
   359
  }
athos@2328
   360
deba@2366
   361
  LpGlpk::Value LpGlpk::_getColLowerBound(int i) const
athos@2328
   362
  {
deba@2441
   363
    int b=LEMON_glp(get_col_type)(lp, i);
athos@2328
   364
      switch (b) {
deba@2441
   365
      case LEMON_GLP(LO):
deba@2441
   366
      case LEMON_GLP(DB):
deba@2441
   367
      case LEMON_GLP(FX):
deba@2441
   368
	return LEMON_glp(get_col_lb)(lp, i);	
athos@2328
   369
      default: ;
athos@2328
   370
	return -INF;
athos@2328
   371
      }
athos@2328
   372
  }
alpar@1321
   373
  
alpar@1321
   374
  void LpGlpk::_setColUpperBound(int i, Value up)
alpar@1321
   375
  {
alpar@1321
   376
    if (up==-INF) {
alpar@1321
   377
      //FIXME error
athos@1261
   378
    }
deba@2441
   379
    int b=LEMON_glp(get_col_type)(lp, i);
deba@2441
   380
    double lo=LEMON_glp(get_col_lb)(lp, i);
alpar@1321
   381
    if (up==INF) {
alpar@1321
   382
      switch (b) {
deba@2441
   383
      case LEMON_GLP(FR):
deba@2441
   384
      case LEMON_GLP(LO):
alpar@1321
   385
	break;
deba@2441
   386
      case LEMON_GLP(UP):
deba@2441
   387
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up);
alpar@1321
   388
	break;
deba@2441
   389
      case LEMON_GLP(DB):
deba@2441
   390
      case LEMON_GLP(FX):
deba@2441
   391
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up);
alpar@1321
   392
	break;
alpar@1321
   393
      default: ;
athos@1261
   394
	//FIXME error
athos@1261
   395
      }
alpar@1321
   396
    } else {
alpar@1321
   397
      switch (b) {
deba@2441
   398
      case LEMON_GLP(FR):
deba@2441
   399
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
alpar@1321
   400
	break;
deba@2441
   401
      case LEMON_GLP(UP):
deba@2441
   402
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
alpar@1321
   403
	break;
deba@2441
   404
      case LEMON_GLP(LO):
deba@2441
   405
      case LEMON_GLP(DB):
deba@2441
   406
      case LEMON_GLP(FX):
alpar@1321
   407
	if (lo==up) 
deba@2441
   408
	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up);
alpar@1321
   409
	else 
deba@2441
   410
	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up);
alpar@1321
   411
	break;
alpar@1321
   412
      default: ;
athos@1261
   413
	//FIXME error
athos@1261
   414
      }
alpar@1321
   415
    }
deba@2441
   416
deba@2441
   417
    solved = false;
alpar@1321
   418
  }
athos@2328
   419
deba@2366
   420
  LpGlpk::Value LpGlpk::_getColUpperBound(int i) const
athos@2328
   421
  {
deba@2441
   422
    int b=LEMON_glp(get_col_type)(lp, i);
athos@2328
   423
      switch (b) {
deba@2441
   424
      case LEMON_GLP(UP):
deba@2441
   425
      case LEMON_GLP(DB):
deba@2441
   426
      case LEMON_GLP(FX):
deba@2441
   427
	return LEMON_glp(get_col_ub)(lp, i);	
athos@2328
   428
      default: ;
athos@2328
   429
	return INF;
athos@2328
   430
      }
athos@2328
   431
  }
alpar@1321
   432
  
athos@1379
   433
  void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
athos@1379
   434
  {
athos@1379
   435
    //Bad parameter
athos@1379
   436
    if (lb==INF || ub==-INF) {
athos@1379
   437
      //FIXME error
athos@1379
   438
    }
athos@1379
   439
athos@1379
   440
    if (lb == -INF){
athos@1379
   441
      if (ub == INF){
deba@2441
   442
	LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FR), lb, ub);
athos@1379
   443
      }
athos@1379
   444
      else{
deba@2441
   445
	LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(UP), lb, ub);
athos@1379
   446
      }
athos@1379
   447
    }
athos@1379
   448
    else{
athos@1379
   449
      if (ub==INF){
deba@2441
   450
	LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(LO), lb, ub);
athos@1379
   451
athos@1379
   452
      }
athos@1379
   453
      else{
athos@1379
   454
	if (lb == ub){
deba@2441
   455
	  LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FX), lb, ub);
athos@1379
   456
	}
athos@1379
   457
	else{
deba@2441
   458
	  LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(DB), lb, ub);
athos@1379
   459
	}
athos@1379
   460
      }
athos@1379
   461
    }
athos@1379
   462
deba@2441
   463
    solved = false;
athos@1379
   464
  }
athos@2328
   465
deba@2366
   466
  void LpGlpk::_getRowBounds(int i, Value &lb, Value &ub) const
athos@2328
   467
  {
athos@2328
   468
deba@2441
   469
    int b=LEMON_glp(get_row_type)(lp, i);
athos@2328
   470
    switch (b) {
deba@2441
   471
    case LEMON_GLP(FR):
deba@2441
   472
    case LEMON_GLP(UP):
athos@2328
   473
      lb = -INF;
athos@2328
   474
	break;
athos@2328
   475
    default: 
deba@2441
   476
      lb=LEMON_glp(get_row_lb)(lp, i);
athos@2328
   477
    }
athos@2328
   478
athos@2328
   479
    switch (b) {
deba@2441
   480
    case LEMON_GLP(FR):
deba@2441
   481
    case LEMON_GLP(LO):
athos@2328
   482
      ub = INF;
athos@2328
   483
	break;
athos@2328
   484
    default: 
deba@2441
   485
      ub=LEMON_glp(get_row_ub)(lp, i);
athos@2328
   486
    }
athos@2328
   487
    
athos@2328
   488
  }
athos@1261
   489
  
athos@1298
   490
  void LpGlpk::_setObjCoeff(int i, Value obj_coef)
athos@1298
   491
  {
athos@1376
   492
    //i=0 means the constant term (shift)
deba@2441
   493
    LEMON_glp(set_obj_coef)(lp, i, obj_coef);
deba@2441
   494
deba@2441
   495
    solved = false;
athos@1298
   496
  }
athos@1261
   497
deba@2366
   498
  LpGlpk::Value LpGlpk::_getObjCoeff(int i) const {
athos@2324
   499
    //i=0 means the constant term (shift)
deba@2441
   500
    return LEMON_glp(get_obj_coef)(lp, i);
athos@2324
   501
  }
athos@2324
   502
athos@1377
   503
  void LpGlpk::_clearObj()
athos@1376
   504
  {
deba@2441
   505
    for (int i=0;i<=LEMON_glp(get_num_cols)(lp);++i){
deba@2441
   506
      LEMON_glp(set_obj_coef)(lp, i, 0);
athos@1376
   507
    }
deba@2441
   508
deba@2441
   509
    solved = false;
athos@1376
   510
  }
alpar@1263
   511
alpar@1303
   512
  LpGlpk::SolveExitStatus LpGlpk::_solve()
alpar@1263
   513
  {
athos@2345
   514
    // A way to check the problem to be solved
deba@2441
   515
    //LEMON_glp(write_cpxlp(lp,"naittvan.cpx");    
athos@2345
   516
deba@2441
   517
    LEMON_lpx(std_basis)(lp);
deba@2441
   518
    int i =  LEMON_lpx(simplex)(lp);
deba@2363
   519
    
athos@1298
   520
    switch (i) {
deba@2441
   521
    case LEMON_LPX(E_OK): 
deba@2441
   522
      solved = true;
athos@1298
   523
      return SOLVED;
athos@1298
   524
    default:
athos@1298
   525
      return UNSOLVED;
athos@1298
   526
    }
alpar@1263
   527
  }
alpar@1263
   528
deba@2366
   529
  LpGlpk::Value LpGlpk::_getPrimal(int i) const
alpar@1263
   530
  {
deba@2441
   531
    return LEMON_glp(get_col_prim)(lp,i);
alpar@1263
   532
  }
marci@1787
   533
deba@2366
   534
  LpGlpk::Value LpGlpk::_getDual(int i) const
marci@1787
   535
  {
deba@2441
   536
    return LEMON_glp(get_row_dual)(lp,i);
marci@1787
   537
  }
alpar@1263
   538
  
deba@2366
   539
  LpGlpk::Value LpGlpk::_getPrimalValue() const
alpar@1312
   540
  {
deba@2441
   541
    return LEMON_glp(get_obj_val)(lp);
alpar@1312
   542
  }
deba@2366
   543
  bool LpGlpk::_isBasicCol(int i) const
deba@2366
   544
  {
deba@2441
   545
    return (LEMON_glp(get_col_stat)(lp, i)==LEMON_GLP(BS));
marci@1840
   546
  }
alpar@1312
   547
  
athos@1298
   548
 
deba@2366
   549
  LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus() const
alpar@1294
   550
  {
deba@2441
   551
    if (!solved) return UNDEFINED;
deba@2441
   552
    int stat=  LEMON_lpx(get_status)(lp);
athos@1298
   553
    switch (stat) {
deba@2441
   554
    case LEMON_LPX(UNDEF)://Undefined (no solve has been run yet)
athos@1298
   555
      return UNDEFINED;
deba@2441
   556
    case LEMON_LPX(NOFEAS)://There is no feasible solution (primal, I guess)
deba@2441
   557
    case LEMON_LPX(INFEAS)://Infeasible 
athos@1458
   558
      return INFEASIBLE;
deba@2441
   559
    case LEMON_LPX(UNBND)://Unbounded
athos@1458
   560
      return INFINITE;
deba@2441
   561
    case LEMON_LPX(FEAS)://Feasible
athos@1458
   562
      return FEASIBLE;
deba@2441
   563
    case LEMON_LPX(OPT)://Feasible
athos@1458
   564
      return OPTIMAL;
athos@1458
   565
    default:
athos@1458
   566
      return UNDEFINED; //to avoid gcc warning
athos@1458
   567
      //FIXME error
athos@1458
   568
    }
athos@1458
   569
  }
athos@1458
   570
deba@2366
   571
  LpGlpk::SolutionStatus LpGlpk::_getDualStatus() const
athos@1458
   572
  {
deba@2441
   573
    if (!solved) return UNDEFINED;
deba@2441
   574
    switch (LEMON_lpx(get_dual_stat)(lp)) {
deba@2441
   575
    case LEMON_LPX(D_UNDEF)://Undefined (no solve has been run yet)
athos@1458
   576
      return UNDEFINED;
deba@2441
   577
    case LEMON_LPX(D_NOFEAS)://There is no dual feasible solution 
deba@2441
   578
//    case LEMON_LPX(D_INFEAS://Infeasible 
athos@1458
   579
      return INFEASIBLE;
deba@2441
   580
    case LEMON_LPX(D_FEAS)://Feasible    
deba@2441
   581
      switch (LEMON_lpx(get_status)(lp)) {
deba@2441
   582
      case LEMON_LPX(NOFEAS):
athos@1458
   583
	return INFINITE;
deba@2441
   584
      case LEMON_LPX(OPT):
athos@1458
   585
	return OPTIMAL;
athos@1458
   586
      default:
athos@1458
   587
	return FEASIBLE;
athos@1458
   588
      }
athos@1458
   589
    default:
athos@1458
   590
      return UNDEFINED; //to avoid gcc warning
athos@1458
   591
      //FIXME error
athos@1458
   592
    }
athos@1458
   593
  }
athos@1458
   594
deba@2366
   595
  LpGlpk::ProblemTypes LpGlpk::_getProblemType() const
athos@1458
   596
  {
deba@2441
   597
    if (!solved) return UNKNOWN;
deba@2441
   598
      //int stat=  LEMON_glp(get_status(lp);
deba@2441
   599
    int statp=  LEMON_lpx(get_prim_stat)(lp);
deba@2441
   600
    int statd=  LEMON_lpx(get_dual_stat)(lp);
deba@2441
   601
    if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_FEAS))
athos@1460
   602
	return PRIMAL_DUAL_FEASIBLE;
deba@2441
   603
    if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_NOFEAS))
athos@1460
   604
	return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
deba@2441
   605
    if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_FEAS))
athos@1460
   606
	return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
deba@2441
   607
    if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_NOFEAS))
athos@1460
   608
	return PRIMAL_DUAL_INFEASIBLE;
athos@1460
   609
    //In all other cases
athos@1460
   610
    return UNKNOWN;
alpar@1294
   611
  }
alpar@1263
   612
alpar@1312
   613
  void LpGlpk::_setMax()
alpar@1312
   614
  {
deba@2441
   615
    solved = false;
deba@2441
   616
    LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MAX));
alpar@1321
   617
  }
alpar@1321
   618
alpar@1312
   619
  void LpGlpk::_setMin()
alpar@1312
   620
  {
deba@2441
   621
    solved = false;
deba@2441
   622
    LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MIN));
alpar@1321
   623
  }
alpar@1321
   624
deba@2366
   625
  bool LpGlpk::_isMax() const
athos@2324
   626
  {
deba@2441
   627
    return (LEMON_glp(get_obj_dir)(lp)==LEMON_GLP(MAX));
athos@2324
   628
  }
athos@2324
   629
alpar@1321
   630
 
athos@2324
   631
alpar@1321
   632
  void LpGlpk::messageLevel(int m)
alpar@1321
   633
  {
deba@2441
   634
    LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_MSGLEV), m);
alpar@1321
   635
  }
alpar@1312
   636
alpar@1326
   637
  void LpGlpk::presolver(bool b)
alpar@1326
   638
  {
deba@2441
   639
    LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_PRESOL), b);
alpar@1326
   640
  }
alpar@1326
   641
alpar@1312
   642
 
athos@1261
   643
} //END OF NAMESPACE LEMON