lemon/lp_glpk.cc
author deba
Fri, 16 Feb 2007 19:11:31 +0000
changeset 2366 bfbdded3763a
parent 2364 3a5e67bd42d2
child 2368 6b2e8b734ae7
permissions -rw-r--r--
Using const in lp interface
colByName functionality
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@1956
     5
 * Copyright (C) 2003-2006
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>
athos@1261
    24
namespace lemon {
athos@1261
    25
alpar@1364
    26
deba@2363
    27
  LpGlpk::LpGlpk() : Parent() {
deba@2363
    28
    rows = _lp_bits::LpId(1);
deba@2363
    29
    cols = _lp_bits::LpId(1);
deba@2363
    30
    lp = lpx_create_prob();
deba@2363
    31
    ///\todo control function for this:
alpar@1321
    32
    lpx_set_int_parm(lp, LPX_K_DUAL, 1);
alpar@1321
    33
    messageLevel(0);
alpar@1321
    34
  }
alpar@1321
    35
  
deba@2363
    36
  LpGlpk::LpGlpk(const LpGlpk &glp) : Parent() {
deba@2363
    37
    rows = _lp_bits::LpId(1);
deba@2363
    38
    cols = _lp_bits::LpId(1);
deba@2363
    39
    lp = lpx_create_prob();
deba@2366
    40
    lpx_create_index(lp);
deba@2363
    41
    ///\todo control function for this:
alpar@2321
    42
    lpx_set_int_parm(lp, LPX_K_DUAL, 1);
alpar@2321
    43
    messageLevel(0);
alpar@2321
    44
    //Coefficient matrix, row bounds
alpar@2321
    45
    lpx_add_rows(lp, lpx_get_num_rows(glp.lp));
alpar@2321
    46
    lpx_add_cols(lp, lpx_get_num_cols(glp.lp));
alpar@2321
    47
    int len;
alpar@2321
    48
    int ind[1+lpx_get_num_cols(glp.lp)];
alpar@2321
    49
    Value val[1+lpx_get_num_cols(glp.lp)];
alpar@2321
    50
    for (int i=1;i<=lpx_get_num_rows(glp.lp);++i)
alpar@2321
    51
      {
alpar@2321
    52
	len=lpx_get_mat_row(glp.lp,i,ind,val);
alpar@2321
    53
	lpx_set_mat_row(lp, i,len,ind,val);
alpar@2321
    54
	lpx_set_row_bnds(lp,i,lpx_get_row_type(glp.lp,i),
alpar@2321
    55
			 lpx_get_row_lb(glp.lp,i),lpx_get_row_ub(glp.lp,i));
alpar@2321
    56
      }
alpar@2321
    57
alpar@2321
    58
    //Objective function, coloumn bounds
alpar@2321
    59
    lpx_set_obj_dir(lp, lpx_get_obj_dir(glp.lp));
alpar@2321
    60
    //Objectif function's constant term treated separately
alpar@2321
    61
    lpx_set_obj_coef(lp,0,lpx_get_obj_coef(glp.lp,0));
alpar@2321
    62
    for (int i=1;i<=lpx_get_num_cols(glp.lp);++i)
alpar@2321
    63
      {
alpar@2321
    64
	lpx_set_obj_coef(lp,i,lpx_get_obj_coef(glp.lp,i));
alpar@2321
    65
	lpx_set_col_bnds(lp,i,lpx_get_col_type(glp.lp,i),
alpar@2321
    66
			 lpx_get_col_lb(glp.lp,i),lpx_get_col_ub(glp.lp,i));
alpar@2321
    67
      }
alpar@2321
    68
  }
alpar@2321
    69
  
alpar@1321
    70
  LpGlpk::~LpGlpk() {
alpar@1321
    71
    lpx_delete_prob(lp);
alpar@1321
    72
  }
alpar@1321
    73
  
alpar@1321
    74
  int LpGlpk::_addCol() { 
alpar@1321
    75
    int i=lpx_add_cols(lp, 1);
alpar@1321
    76
    _setColLowerBound(i, -INF);
alpar@1321
    77
    _setColUpperBound(i, INF);
alpar@1321
    78
    return i;
alpar@1321
    79
  }
alpar@1321
    80
athos@1436
    81
  ///\e
athos@1436
    82
athos@1436
    83
athos@1436
    84
  LpSolverBase &LpGlpk::_newLp()
athos@1436
    85
  {
alpar@2321
    86
    LpGlpk* newlp=new LpGlpk;
athos@1436
    87
    return *newlp;
athos@1436
    88
  }
athos@1436
    89
  
athos@1436
    90
  ///\e
athos@1436
    91
athos@1436
    92
  LpSolverBase &LpGlpk::_copyLp()
athos@1436
    93
  {
alpar@2321
    94
    LpGlpk* newlp=new LpGlpk(*this);
athos@1436
    95
    return *newlp;
athos@1436
    96
  }
athos@1436
    97
alpar@1321
    98
  int LpGlpk::_addRow() { 
alpar@1321
    99
    int i=lpx_add_rows(lp, 1);
alpar@1321
   100
    return i;
alpar@1321
   101
  }
alpar@1321
   102
alpar@1321
   103
  
athos@1432
   104
  void LpGlpk::_eraseCol(int i) {
athos@1432
   105
    int cols[2];
athos@1432
   106
    cols[1]=i;
athos@1432
   107
    lpx_del_cols(lp, 1, cols);
athos@1432
   108
  }
athos@1432
   109
  
athos@1432
   110
  void LpGlpk::_eraseRow(int i) {
athos@1432
   111
    int rows[2];
athos@1432
   112
    rows[1]=i;
athos@1432
   113
    lpx_del_rows(lp, 1, rows);
athos@1432
   114
  }
athos@1432
   115
deba@2366
   116
  void LpGlpk::_getColName(int col, std::string & name) const
alpar@1895
   117
  {
alpar@1895
   118
    
alpar@1895
   119
    char *n = lpx_get_col_name(lp,col);
alpar@1895
   120
    name = n?n:"";
alpar@1895
   121
  }
alpar@1895
   122
  
alpar@1895
   123
  
alpar@1895
   124
  void LpGlpk::_setColName(int col, const std::string & name)
alpar@1895
   125
  {
alpar@1895
   126
    lpx_set_col_name(lp,col,const_cast<char*>(name.c_str()));
athos@2349
   127
alpar@1895
   128
  }
deba@2366
   129
deba@2366
   130
  int LpGlpk::_colByName(const std::string& name) const
deba@2366
   131
  {
deba@2366
   132
    int k = lpx_find_col(lp, const_cast<char*>(name.c_str()));
deba@2366
   133
    return k > 0 ? k : -1; 
deba@2366
   134
  }
deba@2366
   135
alpar@1895
   136
  
deba@2364
   137
  void LpGlpk::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e) 
alpar@1321
   138
  {
deba@2312
   139
    std::vector<int> indices;
deba@2312
   140
    std::vector<Value> values;
deba@2312
   141
deba@2312
   142
    indices.push_back(0);
deba@2312
   143
    values.push_back(0);
deba@2312
   144
deba@2364
   145
    for(ConstRowIterator it=b; it!=e; ++it) {
deba@2312
   146
      indices.push_back(it->first);
deba@2312
   147
      values.push_back(it->second);
deba@2312
   148
    }
deba@2312
   149
deba@2312
   150
    lpx_set_mat_row(lp, i, values.size() - 1, &indices[0], &values[0]);
alpar@1321
   151
  }
deba@2364
   152
deba@2366
   153
  void LpGlpk::_getRowCoeffs(int i, RowIterator b) const
deba@2364
   154
  {
deba@2364
   155
    int length = lpx_get_mat_row(lp, i, 0, 0);
deba@2364
   156
    
deba@2364
   157
    std::vector<int> indices(length + 1);
deba@2364
   158
    std::vector<Value> values(length + 1);
deba@2364
   159
    
deba@2364
   160
    lpx_get_mat_row(lp, i, &indices[0], &values[0]);
deba@2364
   161
    
deba@2364
   162
    for (int i = 1; i <= length; ++i) {
deba@2364
   163
      *b = std::make_pair(indices[i], values[i]);
deba@2364
   164
      ++b;
deba@2364
   165
    }
deba@2364
   166
  }
alpar@1321
   167
  
deba@2364
   168
  void LpGlpk::_setColCoeffs(int i, ConstColIterator b, ConstColIterator e) {
deba@2312
   169
deba@2312
   170
    std::vector<int> indices;
deba@2312
   171
    std::vector<Value> values;
deba@2312
   172
deba@2312
   173
    indices.push_back(0);
deba@2312
   174
    values.push_back(0);
deba@2312
   175
deba@2364
   176
    for(ConstColIterator it=b; it!=e; ++it) {
deba@2312
   177
      indices.push_back(it->first);
deba@2312
   178
      values.push_back(it->second);
deba@2312
   179
    }
deba@2312
   180
    
deba@2312
   181
    lpx_set_mat_col(lp, i, values.size() - 1, &indices[0], &values[0]);
alpar@1321
   182
  }
athos@1431
   183
deba@2366
   184
  void LpGlpk::_getColCoeffs(int i, ColIterator b) const
deba@2364
   185
  {
deba@2364
   186
    int length = lpx_get_mat_col(lp, i, 0, 0);
deba@2364
   187
    
deba@2364
   188
    std::vector<int> indices(length + 1);
deba@2364
   189
    std::vector<Value> values(length + 1);
deba@2364
   190
    
deba@2364
   191
    lpx_get_mat_col(lp, i, &indices[0], &values[0]);
deba@2364
   192
    
deba@2364
   193
    for (int i = 1; i <= length; ++i) {
deba@2364
   194
      *b = std::make_pair(indices[i], values[i]);
deba@2364
   195
      ++b;
deba@2364
   196
    }
deba@2364
   197
  }
athos@1431
   198
athos@1431
   199
  void LpGlpk::_setCoeff(int row, int col, Value value) 
athos@1431
   200
  {
deba@2312
   201
deba@2312
   202
    if (lpx_get_num_cols(lp) < lpx_get_num_rows(lp)) {
deba@2312
   203
deba@2312
   204
      int length=lpx_get_mat_row(lp, row, 0, 0);
deba@2312
   205
      
deba@2312
   206
      std::vector<int> indices(length + 2);
deba@2312
   207
      std::vector<Value> values(length + 2);
deba@2312
   208
      
deba@2312
   209
      lpx_get_mat_row(lp, row, &indices[0], &values[0]);
deba@2312
   210
      
deba@2312
   211
      //The following code does not suppose that the elements of the
deba@2312
   212
      //array indices are sorted
deba@2312
   213
      bool found=false;
deba@2312
   214
      for (int i = 1; i <= length; ++i) {
deba@2312
   215
        if (indices[i]==col){
deba@2312
   216
          found=true;
deba@2312
   217
          values[i]=value;
deba@2312
   218
          break;
deba@2312
   219
        }
deba@2312
   220
      }
deba@2312
   221
      if (!found){
deba@2312
   222
        ++length;
deba@2312
   223
        indices[length]=col;
deba@2312
   224
        values[length]=value;
deba@2312
   225
      }
athos@1431
   226
    
deba@2312
   227
      lpx_set_mat_row(lp, row, length, &indices[0], &values[0]);
deba@2312
   228
deba@2312
   229
    } else {
deba@2312
   230
deba@2312
   231
      int length=lpx_get_mat_col(lp, col, 0, 0);
deba@2312
   232
      
deba@2312
   233
      std::vector<int> indices(length + 2);
deba@2312
   234
      std::vector<Value> values(length + 2);
deba@2312
   235
      
deba@2312
   236
      lpx_get_mat_col(lp, col, &indices[0], &values[0]);
deba@2312
   237
      
deba@2312
   238
      //The following code does not suppose that the elements of the
deba@2312
   239
      //array indices are sorted
deba@2312
   240
      bool found=false;
deba@2312
   241
      for (int i = 1; i <= length; ++i) {
deba@2312
   242
        if (indices[i]==col){
deba@2312
   243
          found=true;
deba@2312
   244
          values[i]=value;
deba@2312
   245
          break;
deba@2312
   246
        }
deba@2312
   247
      }
deba@2312
   248
      if (!found){
deba@2312
   249
        ++length;
deba@2312
   250
        indices[length]=row;
deba@2312
   251
        values[length]=value;
deba@2312
   252
      }
athos@1431
   253
    
deba@2312
   254
      lpx_set_mat_col(lp, col, length, &indices[0], &values[0]);
athos@1431
   255
    }
athos@1431
   256
  }
athos@1431
   257
deba@2366
   258
  LpGlpk::Value LpGlpk::_getCoeff(int row, int col) const
athos@2324
   259
  {
athos@2328
   260
athos@2328
   261
    int length=lpx_get_mat_row(lp, row, 0, 0);
athos@2328
   262
    
deba@2364
   263
    std::vector<int> indices(length + 1);
deba@2364
   264
    std::vector<Value> values(length + 1);
athos@2328
   265
    
athos@2328
   266
    lpx_get_mat_row(lp, row, &indices[0], &values[0]);
athos@2328
   267
    
athos@2328
   268
    //The following code does not suppose that the elements of the
athos@2328
   269
    //array indices are sorted
athos@2328
   270
    for (int i = 1; i <= length; ++i) {
athos@2328
   271
      if (indices[i]==col){
athos@2328
   272
	return values[i];
athos@2328
   273
      }
athos@2328
   274
    }
athos@2324
   275
    return 0;
athos@2328
   276
athos@2324
   277
  }
athos@2324
   278
athos@2324
   279
alpar@1321
   280
  void LpGlpk::_setColLowerBound(int i, Value lo)
alpar@1321
   281
  {
alpar@1321
   282
    if (lo==INF) {
alpar@1321
   283
      //FIXME error
alpar@1321
   284
    }
alpar@1321
   285
    int b=lpx_get_col_type(lp, i);
alpar@1321
   286
    double up=lpx_get_col_ub(lp, i);	
alpar@1321
   287
    if (lo==-INF) {
alpar@1321
   288
      switch (b) {
alpar@1321
   289
      case LPX_FR:
alpar@1321
   290
      case LPX_LO:
alpar@1321
   291
	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
alpar@1321
   292
	break;
alpar@1321
   293
      case LPX_UP:
alpar@1321
   294
	break;
alpar@1321
   295
      case LPX_DB:
alpar@1321
   296
      case LPX_FX:
alpar@1321
   297
	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
alpar@1321
   298
	break;
alpar@1321
   299
      default: ;
alpar@1321
   300
	//FIXME error
alpar@1321
   301
      }
alpar@1321
   302
    } else {
alpar@1321
   303
      switch (b) {
alpar@1321
   304
      case LPX_FR:
alpar@1321
   305
      case LPX_LO:
alpar@1321
   306
	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
alpar@1321
   307
	break;
alpar@1321
   308
      case LPX_UP:	  
alpar@1321
   309
      case LPX_DB:
alpar@1321
   310
      case LPX_FX:
alpar@1321
   311
	if (lo==up) 
alpar@1321
   312
	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
alpar@1321
   313
	else 
alpar@1321
   314
	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
alpar@1321
   315
	break;
alpar@1321
   316
      default: ;
alpar@1321
   317
	//FIXME error
alpar@1321
   318
      }
athos@1261
   319
    }
athos@1261
   320
alpar@1321
   321
  }
athos@2328
   322
deba@2366
   323
  LpGlpk::Value LpGlpk::_getColLowerBound(int i) const
athos@2328
   324
  {
athos@2328
   325
    int b=lpx_get_col_type(lp, i);
athos@2328
   326
      switch (b) {
athos@2328
   327
      case LPX_LO:
athos@2328
   328
      case LPX_DB:
athos@2328
   329
      case LPX_FX:
athos@2328
   330
	return lpx_get_col_lb(lp, i);	
athos@2328
   331
      default: ;
athos@2328
   332
	return -INF;
athos@2328
   333
      }
athos@2328
   334
  }
alpar@1321
   335
  
alpar@1321
   336
  void LpGlpk::_setColUpperBound(int i, Value up)
alpar@1321
   337
  {
alpar@1321
   338
    if (up==-INF) {
alpar@1321
   339
      //FIXME error
athos@1261
   340
    }
alpar@1321
   341
    int b=lpx_get_col_type(lp, i);
alpar@1321
   342
    double lo=lpx_get_col_lb(lp, i);
alpar@1321
   343
    if (up==INF) {
alpar@1321
   344
      switch (b) {
alpar@1321
   345
      case LPX_FR:
alpar@1321
   346
      case LPX_LO:
alpar@1321
   347
	break;
alpar@1321
   348
      case LPX_UP:
alpar@1321
   349
	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
alpar@1321
   350
	break;
alpar@1321
   351
      case LPX_DB:
alpar@1321
   352
      case LPX_FX:
alpar@1321
   353
	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
alpar@1321
   354
	break;
alpar@1321
   355
      default: ;
athos@1261
   356
	//FIXME error
athos@1261
   357
      }
alpar@1321
   358
    } else {
alpar@1321
   359
      switch (b) {
alpar@1321
   360
      case LPX_FR:
alpar@1321
   361
	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
alpar@1321
   362
	break;
alpar@1321
   363
      case LPX_UP:
alpar@1321
   364
	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
alpar@1321
   365
	break;
alpar@1321
   366
      case LPX_LO:
alpar@1321
   367
      case LPX_DB:
alpar@1321
   368
      case LPX_FX:
alpar@1321
   369
	if (lo==up) 
alpar@1321
   370
	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
alpar@1321
   371
	else 
alpar@1321
   372
	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
alpar@1321
   373
	break;
alpar@1321
   374
      default: ;
athos@1261
   375
	//FIXME error
athos@1261
   376
      }
alpar@1321
   377
    }
alpar@1321
   378
  }
athos@2328
   379
deba@2366
   380
  LpGlpk::Value LpGlpk::_getColUpperBound(int i) const
athos@2328
   381
  {
athos@2328
   382
    int b=lpx_get_col_type(lp, i);
athos@2328
   383
      switch (b) {
athos@2328
   384
      case LPX_UP:
athos@2328
   385
      case LPX_DB:
athos@2328
   386
      case LPX_FX:
athos@2328
   387
	return lpx_get_col_ub(lp, i);	
athos@2328
   388
      default: ;
athos@2328
   389
	return INF;
athos@2328
   390
      }
athos@2328
   391
  }
alpar@1321
   392
  
athos@1379
   393
  void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
athos@1379
   394
  {
athos@1379
   395
    //Bad parameter
athos@1379
   396
    if (lb==INF || ub==-INF) {
athos@1379
   397
      //FIXME error
athos@1379
   398
    }
athos@1379
   399
athos@1379
   400
    if (lb == -INF){
athos@1379
   401
      if (ub == INF){
athos@1379
   402
	lpx_set_row_bnds(lp, i, LPX_FR, lb, ub);
athos@1379
   403
      }
athos@1379
   404
      else{
athos@1379
   405
	lpx_set_row_bnds(lp, i, LPX_UP, lb, ub);
athos@1379
   406
      }
athos@1379
   407
    }
athos@1379
   408
    else{
athos@1379
   409
      if (ub==INF){
athos@1379
   410
	lpx_set_row_bnds(lp, i, LPX_LO, lb, ub);
athos@1379
   411
athos@1379
   412
      }
athos@1379
   413
      else{
athos@1379
   414
	if (lb == ub){
athos@1379
   415
	  lpx_set_row_bnds(lp, i, LPX_FX, lb, ub);
athos@1379
   416
	}
athos@1379
   417
	else{
athos@1379
   418
	  lpx_set_row_bnds(lp, i, LPX_DB, lb, ub);
athos@1379
   419
	}
athos@1379
   420
      }
athos@1379
   421
    }
athos@1379
   422
athos@1379
   423
  }
athos@2328
   424
deba@2366
   425
  void LpGlpk::_getRowBounds(int i, Value &lb, Value &ub) const
athos@2328
   426
  {
athos@2328
   427
athos@2328
   428
    int b=lpx_get_row_type(lp, i);
athos@2328
   429
    switch (b) {
athos@2328
   430
    case LPX_FR:
athos@2328
   431
    case LPX_UP:
athos@2328
   432
      lb = -INF;
athos@2328
   433
	break;
athos@2328
   434
    default: 
athos@2328
   435
      lb=lpx_get_row_lb(lp, i);
athos@2328
   436
    }
athos@2328
   437
athos@2328
   438
    switch (b) {
athos@2328
   439
    case LPX_FR:
athos@2328
   440
    case LPX_LO:
athos@2328
   441
      ub = INF;
athos@2328
   442
	break;
athos@2328
   443
    default: 
athos@2328
   444
      ub=lpx_get_row_ub(lp, i);
athos@2328
   445
    }
athos@2328
   446
    
athos@2328
   447
  }
athos@1261
   448
  
athos@1298
   449
  void LpGlpk::_setObjCoeff(int i, Value obj_coef)
athos@1298
   450
  {
athos@1376
   451
    //i=0 means the constant term (shift)
athos@1298
   452
    lpx_set_obj_coef(lp, i, obj_coef);
athos@1298
   453
  }
athos@1261
   454
deba@2366
   455
  LpGlpk::Value LpGlpk::_getObjCoeff(int i) const {
athos@2324
   456
    //i=0 means the constant term (shift)
athos@2324
   457
    return lpx_get_obj_coef(lp, i);
athos@2324
   458
  }
athos@2324
   459
athos@1377
   460
  void LpGlpk::_clearObj()
athos@1376
   461
  {
athos@1377
   462
    for (int i=0;i<=lpx_get_num_cols(lp);++i){
athos@1377
   463
      lpx_set_obj_coef(lp, i, 0);
athos@1376
   464
    }
athos@1376
   465
  }
alpar@1263
   466
alpar@1303
   467
  LpGlpk::SolveExitStatus LpGlpk::_solve()
alpar@1263
   468
  {
athos@2345
   469
    // A way to check the problem to be solved
athos@2345
   470
    //lpx_write_cpxlp(lp,"naittvan.cpx");    
athos@2345
   471
deba@2363
   472
    lpx_std_basis(lp);
athos@1458
   473
    int i =  lpx_simplex(lp);
deba@2363
   474
    
athos@1298
   475
    switch (i) {
athos@1298
   476
    case LPX_E_OK: 
athos@1298
   477
      return SOLVED;
athos@1298
   478
    default:
athos@1298
   479
      return UNSOLVED;
athos@1298
   480
    }
alpar@1263
   481
  }
alpar@1263
   482
deba@2366
   483
  LpGlpk::Value LpGlpk::_getPrimal(int i) const
alpar@1263
   484
  {
athos@1298
   485
    return lpx_get_col_prim(lp,i);
alpar@1263
   486
  }
marci@1787
   487
deba@2366
   488
  LpGlpk::Value LpGlpk::_getDual(int i) const
marci@1787
   489
  {
marci@1787
   490
    return lpx_get_row_dual(lp,i);
marci@1787
   491
  }
alpar@1263
   492
  
deba@2366
   493
  LpGlpk::Value LpGlpk::_getPrimalValue() const
alpar@1312
   494
  {
athos@1314
   495
    return lpx_get_obj_val(lp);
alpar@1312
   496
  }
deba@2366
   497
  bool LpGlpk::_isBasicCol(int i) const
deba@2366
   498
  {
marci@1840
   499
    return (lpx_get_col_stat(lp, i)==LPX_BS);
marci@1840
   500
  }
alpar@1312
   501
  
athos@1298
   502
 
deba@2366
   503
  LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus() const
alpar@1294
   504
  {
athos@1298
   505
    int stat=  lpx_get_status(lp);
athos@1298
   506
    switch (stat) {
athos@1298
   507
    case LPX_UNDEF://Undefined (no solve has been run yet)
athos@1298
   508
      return UNDEFINED;
athos@1458
   509
    case LPX_NOFEAS://There is no feasible solution (primal, I guess)
athos@1458
   510
    case LPX_INFEAS://Infeasible 
athos@1458
   511
      return INFEASIBLE;
athos@1458
   512
    case LPX_UNBND://Unbounded
athos@1458
   513
      return INFINITE;
athos@1458
   514
    case LPX_FEAS://Feasible
athos@1458
   515
      return FEASIBLE;
athos@1458
   516
    case LPX_OPT://Feasible
athos@1458
   517
      return OPTIMAL;
athos@1458
   518
    default:
athos@1458
   519
      return UNDEFINED; //to avoid gcc warning
athos@1458
   520
      //FIXME error
athos@1458
   521
    }
athos@1458
   522
  }
athos@1458
   523
deba@2366
   524
  LpGlpk::SolutionStatus LpGlpk::_getDualStatus() const
athos@1458
   525
  {
alpar@1466
   526
    switch (lpx_get_dual_stat(lp)) {
athos@1458
   527
    case LPX_D_UNDEF://Undefined (no solve has been run yet)
athos@1458
   528
      return UNDEFINED;
athos@1540
   529
    case LPX_D_NOFEAS://There is no dual feasible solution 
athos@1460
   530
//    case LPX_D_INFEAS://Infeasible 
athos@1458
   531
      return INFEASIBLE;
athos@1473
   532
    case LPX_D_FEAS://Feasible    
athos@1473
   533
      switch (lpx_get_status(lp)) {
athos@1473
   534
      case LPX_NOFEAS:
athos@1458
   535
	return INFINITE;
athos@1458
   536
      case LPX_OPT:
athos@1458
   537
	return OPTIMAL;
athos@1458
   538
      default:
athos@1458
   539
	return FEASIBLE;
athos@1458
   540
      }
athos@1458
   541
    default:
athos@1458
   542
      return UNDEFINED; //to avoid gcc warning
athos@1458
   543
      //FIXME error
athos@1458
   544
    }
athos@1458
   545
  }
athos@1458
   546
deba@2366
   547
  LpGlpk::ProblemTypes LpGlpk::_getProblemType() const
athos@1458
   548
  {
athos@1460
   549
      //int stat=  lpx_get_status(lp);
athos@1458
   550
    int statp=  lpx_get_prim_stat(lp);
athos@1458
   551
    int statd=  lpx_get_dual_stat(lp);
athos@1464
   552
    if (statp==LPX_P_FEAS && statd==LPX_D_FEAS)
athos@1460
   553
	return PRIMAL_DUAL_FEASIBLE;
athos@1464
   554
    if (statp==LPX_P_FEAS && statd==LPX_D_NOFEAS)
athos@1460
   555
	return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
athos@1464
   556
    if (statp==LPX_P_NOFEAS && statd==LPX_D_FEAS)
athos@1460
   557
	return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
athos@1464
   558
    if (statp==LPX_P_NOFEAS && statd==LPX_D_NOFEAS)
athos@1460
   559
	return PRIMAL_DUAL_INFEASIBLE;
athos@1460
   560
    //In all other cases
athos@1460
   561
    return UNKNOWN;
alpar@1294
   562
  }
alpar@1263
   563
alpar@1312
   564
  void LpGlpk::_setMax()
alpar@1312
   565
  {
alpar@1321
   566
    lpx_set_obj_dir(lp, LPX_MAX);
alpar@1321
   567
  }
alpar@1321
   568
alpar@1312
   569
  void LpGlpk::_setMin()
alpar@1312
   570
  {
alpar@1321
   571
    lpx_set_obj_dir(lp, LPX_MIN);
alpar@1321
   572
  }
alpar@1321
   573
deba@2366
   574
  bool LpGlpk::_isMax() const
athos@2324
   575
  {
athos@2324
   576
    return (lpx_get_obj_dir(lp)==LPX_MAX);
athos@2324
   577
  }
athos@2324
   578
alpar@1321
   579
 
athos@2324
   580
alpar@1321
   581
  void LpGlpk::messageLevel(int m)
alpar@1321
   582
  {
alpar@1321
   583
    lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
alpar@1321
   584
  }
alpar@1312
   585
alpar@1326
   586
  void LpGlpk::presolver(bool b)
alpar@1326
   587
  {
alpar@1326
   588
    lpx_set_int_parm(lp, LPX_K_PRESOL, b);
alpar@1326
   589
  }
alpar@1326
   590
alpar@1312
   591
 
athos@1261
   592
} //END OF NAMESPACE LEMON