lemon/lp_glpk.cc
author kpeter
Mon, 18 Feb 2008 03:32:06 +0000
changeset 2575 e866e288cba6
parent 2441 d8d6ab871608
child 2591 3b4d5bc3b4fb
permissions -rw-r--r--
Major improvements in NetworkSimplex.

Main changes:
- Use -potenital[] instead of potential[] to conform to the usual
terminology.
- Use function parameter instead of #define commands to select pivot rule.
- Use much faster implementation for the candidate list pivot rule.
It is about 5-20 times faster now.
- Add a new pivot rule called "Limited Search" that is a modified
version of "Block Search". It is about 25 percent faster on rather
sparse graphs.
- By default "Limited Search" is used for sparse graphs and
"Block Search" is used otherwise. This combined method is the most
efficient on every input class.
- Change the name of private members to start with "_".
- Change the name of function parameters not to start with "_".
- Remove unnecessary documentation for private members.
- Many doc improvements.
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;
deba@2441
    67
    int ind[1+LEMON_glp(get_num_cols)(glp.lp)];
deba@2441
    68
    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
      {
deba@2441
    71
	len=LEMON_glp(get_mat_row)(glp.lp,i,ind,val);
deba@2441
    72
	LEMON_glp(set_mat_row)(lp, i,len,ind,val);
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
      }
alpar@2321
    92
  }
alpar@2321
    93
  
alpar@1321
    94
  LpGlpk::~LpGlpk() {
deba@2441
    95
    LEMON_glp(delete_prob)(lp);
alpar@1321
    96
  }
alpar@1321
    97
  
alpar@1321
    98
  int LpGlpk::_addCol() { 
deba@2441
    99
    int i=LEMON_glp(add_cols)(lp, 1);
deba@2441
   100
    LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), 0.0, 0.0);
deba@2441
   101
    solved = false;
alpar@1321
   102
    return i;
alpar@1321
   103
  }
alpar@1321
   104
athos@1436
   105
  ///\e
athos@1436
   106
athos@1436
   107
athos@1436
   108
  LpSolverBase &LpGlpk::_newLp()
athos@1436
   109
  {
alpar@2321
   110
    LpGlpk* newlp=new LpGlpk;
athos@1436
   111
    return *newlp;
athos@1436
   112
  }
athos@1436
   113
  
athos@1436
   114
  ///\e
athos@1436
   115
athos@1436
   116
  LpSolverBase &LpGlpk::_copyLp()
athos@1436
   117
  {
alpar@2321
   118
    LpGlpk* newlp=new LpGlpk(*this);
athos@1436
   119
    return *newlp;
athos@1436
   120
  }
athos@1436
   121
alpar@1321
   122
  int LpGlpk::_addRow() { 
deba@2441
   123
    int i=LEMON_glp(add_rows)(lp, 1);
deba@2441
   124
    solved = false;
alpar@1321
   125
    return i;
alpar@1321
   126
  }
alpar@1321
   127
alpar@1321
   128
  
athos@1432
   129
  void LpGlpk::_eraseCol(int i) {
deba@2386
   130
    int ca[2];
deba@2386
   131
    ca[1]=i;
deba@2441
   132
    LEMON_glp(del_cols)(lp, 1, ca);
deba@2441
   133
    solved = false;
athos@1432
   134
  }
athos@1432
   135
  
athos@1432
   136
  void LpGlpk::_eraseRow(int i) {
deba@2386
   137
    int ra[2];
deba@2386
   138
    ra[1]=i;
deba@2441
   139
    LEMON_glp(del_rows)(lp, 1, ra);
deba@2441
   140
    solved = false;
athos@1432
   141
  }
athos@1432
   142
deba@2386
   143
  void LpGlpk::_getColName(int c, std::string & name) const
alpar@1895
   144
  {
alpar@1895
   145
    
deba@2441
   146
    const char *n = LEMON_glp(get_col_name)(lp,c);
alpar@1895
   147
    name = n?n:"";
alpar@1895
   148
  }
alpar@1895
   149
  
alpar@1895
   150
  
deba@2386
   151
  void LpGlpk::_setColName(int c, const std::string & name)
alpar@1895
   152
  {
deba@2441
   153
    LEMON_glp(set_col_name)(lp,c,const_cast<char*>(name.c_str()));
athos@2349
   154
alpar@1895
   155
  }
deba@2366
   156
deba@2366
   157
  int LpGlpk::_colByName(const std::string& name) const
deba@2366
   158
  {
deba@2441
   159
    int k = LEMON_glp(find_col)(lp, const_cast<char*>(name.c_str()));
deba@2366
   160
    return k > 0 ? k : -1; 
deba@2366
   161
  }
deba@2366
   162
alpar@1895
   163
  
deba@2364
   164
  void LpGlpk::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e) 
alpar@1321
   165
  {
deba@2312
   166
    std::vector<int> indices;
deba@2312
   167
    std::vector<Value> values;
deba@2312
   168
deba@2312
   169
    indices.push_back(0);
deba@2312
   170
    values.push_back(0);
deba@2312
   171
deba@2364
   172
    for(ConstRowIterator it=b; it!=e; ++it) {
deba@2312
   173
      indices.push_back(it->first);
deba@2312
   174
      values.push_back(it->second);
deba@2312
   175
    }
deba@2312
   176
deba@2441
   177
    LEMON_glp(set_mat_row)(lp, i, values.size() - 1, 
deba@2441
   178
				&indices[0], &values[0]);
deba@2441
   179
deba@2441
   180
    solved = false;
alpar@1321
   181
  }
deba@2364
   182
deba@2386
   183
  void LpGlpk::_getRowCoeffs(int ix, RowIterator b) const
deba@2364
   184
  {
deba@2441
   185
    int length = LEMON_glp(get_mat_row)(lp, ix, 0, 0);
deba@2364
   186
    
deba@2364
   187
    std::vector<int> indices(length + 1);
deba@2364
   188
    std::vector<Value> values(length + 1);
deba@2364
   189
    
deba@2441
   190
    LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
deba@2364
   191
    
deba@2364
   192
    for (int i = 1; i <= length; ++i) {
deba@2364
   193
      *b = std::make_pair(indices[i], values[i]);
deba@2364
   194
      ++b;
deba@2364
   195
    }
deba@2364
   196
  }
alpar@1321
   197
  
deba@2386
   198
  void LpGlpk::_setColCoeffs(int ix, ConstColIterator b, ConstColIterator e) {
deba@2312
   199
deba@2312
   200
    std::vector<int> indices;
deba@2312
   201
    std::vector<Value> values;
deba@2312
   202
deba@2312
   203
    indices.push_back(0);
deba@2312
   204
    values.push_back(0);
deba@2312
   205
deba@2364
   206
    for(ConstColIterator it=b; it!=e; ++it) {
deba@2312
   207
      indices.push_back(it->first);
deba@2312
   208
      values.push_back(it->second);
deba@2312
   209
    }
deba@2312
   210
    
deba@2441
   211
    LEMON_glp(set_mat_col)(lp, ix, values.size() - 1, 
deba@2441
   212
				&indices[0], &values[0]);
deba@2441
   213
deba@2441
   214
    solved = false;
alpar@1321
   215
  }
athos@1431
   216
deba@2386
   217
  void LpGlpk::_getColCoeffs(int ix, ColIterator b) const
deba@2364
   218
  {
deba@2441
   219
    int length = LEMON_glp(get_mat_col)(lp, ix, 0, 0);
deba@2364
   220
    
deba@2364
   221
    std::vector<int> indices(length + 1);
deba@2364
   222
    std::vector<Value> values(length + 1);
deba@2364
   223
    
deba@2441
   224
    LEMON_glp(get_mat_col)(lp, ix, &indices[0], &values[0]);
deba@2364
   225
    
deba@2364
   226
    for (int i = 1; i <= length; ++i) {
deba@2364
   227
      *b = std::make_pair(indices[i], values[i]);
deba@2364
   228
      ++b;
deba@2364
   229
    }
deba@2364
   230
  }
athos@1431
   231
deba@2386
   232
  void LpGlpk::_setCoeff(int ix, int jx, Value value) 
athos@1431
   233
  {
deba@2312
   234
deba@2441
   235
    if (LEMON_glp(get_num_cols)(lp) < LEMON_glp(get_num_rows)(lp)) {
deba@2312
   236
deba@2441
   237
      int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0);
deba@2312
   238
      
deba@2312
   239
      std::vector<int> indices(length + 2);
deba@2312
   240
      std::vector<Value> values(length + 2);
deba@2312
   241
      
deba@2441
   242
      LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
deba@2312
   243
      
deba@2312
   244
      //The following code does not suppose that the elements of the
deba@2312
   245
      //array indices are sorted
deba@2312
   246
      bool found=false;
deba@2312
   247
      for (int i = 1; i <= length; ++i) {
deba@2386
   248
        if (indices[i]==jx){
deba@2312
   249
          found=true;
deba@2312
   250
          values[i]=value;
deba@2312
   251
          break;
deba@2312
   252
        }
deba@2312
   253
      }
deba@2312
   254
      if (!found){
deba@2312
   255
        ++length;
deba@2386
   256
        indices[length]=jx;
deba@2312
   257
        values[length]=value;
deba@2312
   258
      }
athos@1431
   259
    
deba@2441
   260
      LEMON_glp(set_mat_row)(lp, ix, length, &indices[0], &values[0]);
deba@2312
   261
deba@2312
   262
    } else {
deba@2312
   263
deba@2441
   264
      int length=LEMON_glp(get_mat_col)(lp, jx, 0, 0);
deba@2312
   265
      
deba@2312
   266
      std::vector<int> indices(length + 2);
deba@2312
   267
      std::vector<Value> values(length + 2);
deba@2312
   268
      
deba@2441
   269
      LEMON_glp(get_mat_col)(lp, jx, &indices[0], &values[0]);
deba@2312
   270
      
deba@2312
   271
      //The following code does not suppose that the elements of the
deba@2312
   272
      //array indices are sorted
deba@2312
   273
      bool found=false;
deba@2312
   274
      for (int i = 1; i <= length; ++i) {
deba@2386
   275
        if (indices[i]==jx){
deba@2312
   276
          found=true;
deba@2312
   277
          values[i]=value;
deba@2312
   278
          break;
deba@2312
   279
        }
deba@2312
   280
      }
deba@2312
   281
      if (!found){
deba@2312
   282
        ++length;
deba@2386
   283
        indices[length]=ix;
deba@2312
   284
        values[length]=value;
deba@2312
   285
      }
athos@1431
   286
    
deba@2441
   287
      LEMON_glp(set_mat_col)(lp, jx, length, &indices[0], &values[0]);
athos@1431
   288
    }
deba@2441
   289
deba@2441
   290
    solved = false;
athos@1431
   291
  }
athos@1431
   292
deba@2386
   293
  LpGlpk::Value LpGlpk::_getCoeff(int ix, int jx) const
athos@2324
   294
  {
athos@2328
   295
deba@2441
   296
    int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0);
athos@2328
   297
    
deba@2364
   298
    std::vector<int> indices(length + 1);
deba@2364
   299
    std::vector<Value> values(length + 1);
athos@2328
   300
    
deba@2441
   301
    LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
athos@2328
   302
    
athos@2328
   303
    //The following code does not suppose that the elements of the
athos@2328
   304
    //array indices are sorted
athos@2328
   305
    for (int i = 1; i <= length; ++i) {
deba@2386
   306
      if (indices[i]==jx){
athos@2328
   307
	return values[i];
athos@2328
   308
      }
athos@2328
   309
    }
athos@2324
   310
    return 0;
athos@2328
   311
athos@2324
   312
  }
athos@2324
   313
athos@2324
   314
alpar@1321
   315
  void LpGlpk::_setColLowerBound(int i, Value lo)
alpar@1321
   316
  {
alpar@1321
   317
    if (lo==INF) {
alpar@1321
   318
      //FIXME error
alpar@1321
   319
    }
deba@2441
   320
    int b=LEMON_glp(get_col_type)(lp, i);
deba@2441
   321
    double up=LEMON_glp(get_col_ub)(lp, i);	
alpar@1321
   322
    if (lo==-INF) {
alpar@1321
   323
      switch (b) {
deba@2441
   324
      case LEMON_GLP(FR):
deba@2441
   325
      case LEMON_GLP(LO):
deba@2441
   326
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up);
alpar@1321
   327
	break;
deba@2441
   328
      case LEMON_GLP(UP):
alpar@1321
   329
	break;
deba@2441
   330
      case LEMON_GLP(DB):
deba@2441
   331
      case LEMON_GLP(FX):
deba@2441
   332
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
alpar@1321
   333
	break;
alpar@1321
   334
      default: ;
alpar@1321
   335
	//FIXME error
alpar@1321
   336
      }
alpar@1321
   337
    } else {
alpar@1321
   338
      switch (b) {
deba@2441
   339
      case LEMON_GLP(FR):
deba@2441
   340
      case LEMON_GLP(LO):
deba@2441
   341
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up);
alpar@1321
   342
	break;
deba@2441
   343
      case LEMON_GLP(UP):	  
deba@2441
   344
      case LEMON_GLP(DB):
deba@2441
   345
      case LEMON_GLP(FX):
alpar@1321
   346
	if (lo==up) 
deba@2441
   347
	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up);
alpar@1321
   348
	else 
deba@2441
   349
	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up);
alpar@1321
   350
	break;
alpar@1321
   351
      default: ;
alpar@1321
   352
	//FIXME error
alpar@1321
   353
      }
athos@1261
   354
    }
athos@1261
   355
deba@2441
   356
    solved = false;
alpar@1321
   357
  }
athos@2328
   358
deba@2366
   359
  LpGlpk::Value LpGlpk::_getColLowerBound(int i) const
athos@2328
   360
  {
deba@2441
   361
    int b=LEMON_glp(get_col_type)(lp, i);
athos@2328
   362
      switch (b) {
deba@2441
   363
      case LEMON_GLP(LO):
deba@2441
   364
      case LEMON_GLP(DB):
deba@2441
   365
      case LEMON_GLP(FX):
deba@2441
   366
	return LEMON_glp(get_col_lb)(lp, i);	
athos@2328
   367
      default: ;
athos@2328
   368
	return -INF;
athos@2328
   369
      }
athos@2328
   370
  }
alpar@1321
   371
  
alpar@1321
   372
  void LpGlpk::_setColUpperBound(int i, Value up)
alpar@1321
   373
  {
alpar@1321
   374
    if (up==-INF) {
alpar@1321
   375
      //FIXME error
athos@1261
   376
    }
deba@2441
   377
    int b=LEMON_glp(get_col_type)(lp, i);
deba@2441
   378
    double lo=LEMON_glp(get_col_lb)(lp, i);
alpar@1321
   379
    if (up==INF) {
alpar@1321
   380
      switch (b) {
deba@2441
   381
      case LEMON_GLP(FR):
deba@2441
   382
      case LEMON_GLP(LO):
alpar@1321
   383
	break;
deba@2441
   384
      case LEMON_GLP(UP):
deba@2441
   385
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up);
alpar@1321
   386
	break;
deba@2441
   387
      case LEMON_GLP(DB):
deba@2441
   388
      case LEMON_GLP(FX):
deba@2441
   389
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up);
alpar@1321
   390
	break;
alpar@1321
   391
      default: ;
athos@1261
   392
	//FIXME error
athos@1261
   393
      }
alpar@1321
   394
    } else {
alpar@1321
   395
      switch (b) {
deba@2441
   396
      case LEMON_GLP(FR):
deba@2441
   397
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
alpar@1321
   398
	break;
deba@2441
   399
      case LEMON_GLP(UP):
deba@2441
   400
	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
alpar@1321
   401
	break;
deba@2441
   402
      case LEMON_GLP(LO):
deba@2441
   403
      case LEMON_GLP(DB):
deba@2441
   404
      case LEMON_GLP(FX):
alpar@1321
   405
	if (lo==up) 
deba@2441
   406
	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up);
alpar@1321
   407
	else 
deba@2441
   408
	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up);
alpar@1321
   409
	break;
alpar@1321
   410
      default: ;
athos@1261
   411
	//FIXME error
athos@1261
   412
      }
alpar@1321
   413
    }
deba@2441
   414
deba@2441
   415
    solved = false;
alpar@1321
   416
  }
athos@2328
   417
deba@2366
   418
  LpGlpk::Value LpGlpk::_getColUpperBound(int i) const
athos@2328
   419
  {
deba@2441
   420
    int b=LEMON_glp(get_col_type)(lp, i);
athos@2328
   421
      switch (b) {
deba@2441
   422
      case LEMON_GLP(UP):
deba@2441
   423
      case LEMON_GLP(DB):
deba@2441
   424
      case LEMON_GLP(FX):
deba@2441
   425
	return LEMON_glp(get_col_ub)(lp, i);	
athos@2328
   426
      default: ;
athos@2328
   427
	return INF;
athos@2328
   428
      }
athos@2328
   429
  }
alpar@1321
   430
  
athos@1379
   431
  void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
athos@1379
   432
  {
athos@1379
   433
    //Bad parameter
athos@1379
   434
    if (lb==INF || ub==-INF) {
athos@1379
   435
      //FIXME error
athos@1379
   436
    }
athos@1379
   437
athos@1379
   438
    if (lb == -INF){
athos@1379
   439
      if (ub == INF){
deba@2441
   440
	LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FR), lb, ub);
athos@1379
   441
      }
athos@1379
   442
      else{
deba@2441
   443
	LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(UP), lb, ub);
athos@1379
   444
      }
athos@1379
   445
    }
athos@1379
   446
    else{
athos@1379
   447
      if (ub==INF){
deba@2441
   448
	LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(LO), lb, ub);
athos@1379
   449
athos@1379
   450
      }
athos@1379
   451
      else{
athos@1379
   452
	if (lb == ub){
deba@2441
   453
	  LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FX), lb, ub);
athos@1379
   454
	}
athos@1379
   455
	else{
deba@2441
   456
	  LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(DB), lb, ub);
athos@1379
   457
	}
athos@1379
   458
      }
athos@1379
   459
    }
athos@1379
   460
deba@2441
   461
    solved = false;
athos@1379
   462
  }
athos@2328
   463
deba@2366
   464
  void LpGlpk::_getRowBounds(int i, Value &lb, Value &ub) const
athos@2328
   465
  {
athos@2328
   466
deba@2441
   467
    int b=LEMON_glp(get_row_type)(lp, i);
athos@2328
   468
    switch (b) {
deba@2441
   469
    case LEMON_GLP(FR):
deba@2441
   470
    case LEMON_GLP(UP):
athos@2328
   471
      lb = -INF;
athos@2328
   472
	break;
athos@2328
   473
    default: 
deba@2441
   474
      lb=LEMON_glp(get_row_lb)(lp, i);
athos@2328
   475
    }
athos@2328
   476
athos@2328
   477
    switch (b) {
deba@2441
   478
    case LEMON_GLP(FR):
deba@2441
   479
    case LEMON_GLP(LO):
athos@2328
   480
      ub = INF;
athos@2328
   481
	break;
athos@2328
   482
    default: 
deba@2441
   483
      ub=LEMON_glp(get_row_ub)(lp, i);
athos@2328
   484
    }
athos@2328
   485
    
athos@2328
   486
  }
athos@1261
   487
  
athos@1298
   488
  void LpGlpk::_setObjCoeff(int i, Value obj_coef)
athos@1298
   489
  {
athos@1376
   490
    //i=0 means the constant term (shift)
deba@2441
   491
    LEMON_glp(set_obj_coef)(lp, i, obj_coef);
deba@2441
   492
deba@2441
   493
    solved = false;
athos@1298
   494
  }
athos@1261
   495
deba@2366
   496
  LpGlpk::Value LpGlpk::_getObjCoeff(int i) const {
athos@2324
   497
    //i=0 means the constant term (shift)
deba@2441
   498
    return LEMON_glp(get_obj_coef)(lp, i);
athos@2324
   499
  }
athos@2324
   500
athos@1377
   501
  void LpGlpk::_clearObj()
athos@1376
   502
  {
deba@2441
   503
    for (int i=0;i<=LEMON_glp(get_num_cols)(lp);++i){
deba@2441
   504
      LEMON_glp(set_obj_coef)(lp, i, 0);
athos@1376
   505
    }
deba@2441
   506
deba@2441
   507
    solved = false;
athos@1376
   508
  }
alpar@1263
   509
alpar@1303
   510
  LpGlpk::SolveExitStatus LpGlpk::_solve()
alpar@1263
   511
  {
athos@2345
   512
    // A way to check the problem to be solved
deba@2441
   513
    //LEMON_glp(write_cpxlp(lp,"naittvan.cpx");    
athos@2345
   514
deba@2441
   515
    LEMON_lpx(std_basis)(lp);
deba@2441
   516
    int i =  LEMON_lpx(simplex)(lp);
deba@2363
   517
    
athos@1298
   518
    switch (i) {
deba@2441
   519
    case LEMON_LPX(E_OK): 
deba@2441
   520
      solved = true;
athos@1298
   521
      return SOLVED;
athos@1298
   522
    default:
athos@1298
   523
      return UNSOLVED;
athos@1298
   524
    }
alpar@1263
   525
  }
alpar@1263
   526
deba@2366
   527
  LpGlpk::Value LpGlpk::_getPrimal(int i) const
alpar@1263
   528
  {
deba@2441
   529
    return LEMON_glp(get_col_prim)(lp,i);
alpar@1263
   530
  }
marci@1787
   531
deba@2366
   532
  LpGlpk::Value LpGlpk::_getDual(int i) const
marci@1787
   533
  {
deba@2441
   534
    return LEMON_glp(get_row_dual)(lp,i);
marci@1787
   535
  }
alpar@1263
   536
  
deba@2366
   537
  LpGlpk::Value LpGlpk::_getPrimalValue() const
alpar@1312
   538
  {
deba@2441
   539
    return LEMON_glp(get_obj_val)(lp);
alpar@1312
   540
  }
deba@2366
   541
  bool LpGlpk::_isBasicCol(int i) const
deba@2366
   542
  {
deba@2441
   543
    return (LEMON_glp(get_col_stat)(lp, i)==LEMON_GLP(BS));
marci@1840
   544
  }
alpar@1312
   545
  
athos@1298
   546
 
deba@2366
   547
  LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus() const
alpar@1294
   548
  {
deba@2441
   549
    if (!solved) return UNDEFINED;
deba@2441
   550
    int stat=  LEMON_lpx(get_status)(lp);
athos@1298
   551
    switch (stat) {
deba@2441
   552
    case LEMON_LPX(UNDEF)://Undefined (no solve has been run yet)
athos@1298
   553
      return UNDEFINED;
deba@2441
   554
    case LEMON_LPX(NOFEAS)://There is no feasible solution (primal, I guess)
deba@2441
   555
    case LEMON_LPX(INFEAS)://Infeasible 
athos@1458
   556
      return INFEASIBLE;
deba@2441
   557
    case LEMON_LPX(UNBND)://Unbounded
athos@1458
   558
      return INFINITE;
deba@2441
   559
    case LEMON_LPX(FEAS)://Feasible
athos@1458
   560
      return FEASIBLE;
deba@2441
   561
    case LEMON_LPX(OPT)://Feasible
athos@1458
   562
      return OPTIMAL;
athos@1458
   563
    default:
athos@1458
   564
      return UNDEFINED; //to avoid gcc warning
athos@1458
   565
      //FIXME error
athos@1458
   566
    }
athos@1458
   567
  }
athos@1458
   568
deba@2366
   569
  LpGlpk::SolutionStatus LpGlpk::_getDualStatus() const
athos@1458
   570
  {
deba@2441
   571
    if (!solved) return UNDEFINED;
deba@2441
   572
    switch (LEMON_lpx(get_dual_stat)(lp)) {
deba@2441
   573
    case LEMON_LPX(D_UNDEF)://Undefined (no solve has been run yet)
athos@1458
   574
      return UNDEFINED;
deba@2441
   575
    case LEMON_LPX(D_NOFEAS)://There is no dual feasible solution 
deba@2441
   576
//    case LEMON_LPX(D_INFEAS://Infeasible 
athos@1458
   577
      return INFEASIBLE;
deba@2441
   578
    case LEMON_LPX(D_FEAS)://Feasible    
deba@2441
   579
      switch (LEMON_lpx(get_status)(lp)) {
deba@2441
   580
      case LEMON_LPX(NOFEAS):
athos@1458
   581
	return INFINITE;
deba@2441
   582
      case LEMON_LPX(OPT):
athos@1458
   583
	return OPTIMAL;
athos@1458
   584
      default:
athos@1458
   585
	return FEASIBLE;
athos@1458
   586
      }
athos@1458
   587
    default:
athos@1458
   588
      return UNDEFINED; //to avoid gcc warning
athos@1458
   589
      //FIXME error
athos@1458
   590
    }
athos@1458
   591
  }
athos@1458
   592
deba@2366
   593
  LpGlpk::ProblemTypes LpGlpk::_getProblemType() const
athos@1458
   594
  {
deba@2441
   595
    if (!solved) return UNKNOWN;
deba@2441
   596
      //int stat=  LEMON_glp(get_status(lp);
deba@2441
   597
    int statp=  LEMON_lpx(get_prim_stat)(lp);
deba@2441
   598
    int statd=  LEMON_lpx(get_dual_stat)(lp);
deba@2441
   599
    if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_FEAS))
athos@1460
   600
	return PRIMAL_DUAL_FEASIBLE;
deba@2441
   601
    if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_NOFEAS))
athos@1460
   602
	return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
deba@2441
   603
    if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_FEAS))
athos@1460
   604
	return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
deba@2441
   605
    if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_NOFEAS))
athos@1460
   606
	return PRIMAL_DUAL_INFEASIBLE;
athos@1460
   607
    //In all other cases
athos@1460
   608
    return UNKNOWN;
alpar@1294
   609
  }
alpar@1263
   610
alpar@1312
   611
  void LpGlpk::_setMax()
alpar@1312
   612
  {
deba@2441
   613
    solved = false;
deba@2441
   614
    LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MAX));
alpar@1321
   615
  }
alpar@1321
   616
alpar@1312
   617
  void LpGlpk::_setMin()
alpar@1312
   618
  {
deba@2441
   619
    solved = false;
deba@2441
   620
    LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MIN));
alpar@1321
   621
  }
alpar@1321
   622
deba@2366
   623
  bool LpGlpk::_isMax() const
athos@2324
   624
  {
deba@2441
   625
    return (LEMON_glp(get_obj_dir)(lp)==LEMON_GLP(MAX));
athos@2324
   626
  }
athos@2324
   627
alpar@1321
   628
 
athos@2324
   629
alpar@1321
   630
  void LpGlpk::messageLevel(int m)
alpar@1321
   631
  {
deba@2441
   632
    LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_MSGLEV), m);
alpar@1321
   633
  }
alpar@1312
   634
alpar@1326
   635
  void LpGlpk::presolver(bool b)
alpar@1326
   636
  {
deba@2441
   637
    LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_PRESOL), b);
alpar@1326
   638
  }
alpar@1326
   639
alpar@1312
   640
 
athos@1261
   641
} //END OF NAMESPACE LEMON