src/work/marci/lp/lp_solver_wrapper_2.h
author deba
Fri, 28 Jan 2005 15:37:08 +0000
changeset 1106 0a7d604a9763
parent 1031 0b7169db694f
permissions -rw-r--r--
Concept modification to resolve the item by its ID.
marci@1031
     1
// -*- c++ -*-
marci@1031
     2
#ifndef LEMON_LP_SOLVER_WRAPPER_H
marci@1031
     3
#define LEMON_LP_SOLVER_WRAPPER_H
marci@1031
     4
marci@1031
     5
///\ingroup misc
marci@1031
     6
///\file
marci@1031
     7
///\brief Dijkstra algorithm.
marci@1031
     8
marci@1031
     9
// #include <stdio.h>
marci@1031
    10
#include <stdlib.h>
marci@1031
    11
// #include <stdio>
marci@1031
    12
//#include <stdlib>
marci@1031
    13
extern "C" {
marci@1031
    14
#include "glpk.h"
marci@1031
    15
}
marci@1031
    16
marci@1031
    17
#include <iostream>
marci@1031
    18
#include <vector>
marci@1031
    19
#include <string>
marci@1031
    20
#include <list>
marci@1031
    21
#include <memory>
marci@1031
    22
#include <utility>
marci@1031
    23
marci@1031
    24
//#include <sage_graph.h>
marci@1031
    25
//#include <lemon/list_graph.h>
marci@1031
    26
//#include <lemon/graph_wrapper.h>
marci@1031
    27
#include <lemon/invalid.h>
marci@1031
    28
//#include <bfs_dfs.h>
marci@1031
    29
//#include <stp.h>
marci@1031
    30
//#include <lemon/max_flow.h>
marci@1031
    31
//#include <augmenting_flow.h>
marci@1031
    32
//#include <iter_map.h>
marci@1031
    33
marci@1031
    34
using std::cout;
marci@1031
    35
using std::cin;
marci@1031
    36
using std::endl;
marci@1031
    37
marci@1031
    38
namespace lemon {
marci@1031
    39
marci@1031
    40
  
marci@1031
    41
  /// \addtogroup misc
marci@1031
    42
  /// @{
marci@1031
    43
marci@1031
    44
  /// \brief A partitioned vector with iterable classes.
marci@1031
    45
  ///
marci@1031
    46
  /// This class implements a container in which the data is stored in an 
marci@1031
    47
  /// stl vector, the range is partitioned into sets and each set is 
marci@1031
    48
  /// doubly linked in a list. 
marci@1031
    49
  /// That is, each class is iterable by lemon iterators, and any member of 
marci@1031
    50
  /// the vector can bo moved to an other class.
marci@1031
    51
  template <typename T>
marci@1031
    52
  class IterablePartition {
marci@1031
    53
  protected:
marci@1031
    54
    struct Node {
marci@1031
    55
      T data;
marci@1031
    56
      int prev; //invalid az -1
marci@1031
    57
      int next; 
marci@1031
    58
    };
marci@1031
    59
    std::vector<Node> nodes;
marci@1031
    60
    struct Tip {
marci@1031
    61
      int first;
marci@1031
    62
      int last;
marci@1031
    63
    };
marci@1031
    64
    std::vector<Tip> tips;
marci@1031
    65
  public:
marci@1031
    66
    /// The classes are indexed by integers from \c 0 to \c classNum()-1.
marci@1031
    67
    int classNum() const { return tips.size(); }
marci@1031
    68
    /// This lemon style iterator iterates through a class. 
marci@1031
    69
    class ClassIt;
marci@1031
    70
    /// Constructor. The number of classes is to be given which is fixed 
marci@1031
    71
    /// over the life of the container. 
marci@1031
    72
    /// The partition classes are indexed from 0 to class_num-1. 
marci@1031
    73
    IterablePartition(int class_num) { 
marci@1031
    74
      for (int i=0; i<class_num; ++i) {
marci@1031
    75
	Tip t;
marci@1031
    76
	t.first=t.last=-1;
marci@1031
    77
	tips.push_back(t);
marci@1031
    78
      }
marci@1031
    79
    }
marci@1031
    80
  protected:
marci@1031
    81
    void befuz(ClassIt it, int class_id) {
marci@1031
    82
      if (tips[class_id].first==-1) {
marci@1031
    83
	if (tips[class_id].last==-1) {
marci@1031
    84
	  nodes[it.i].prev=nodes[it.i].next=-1;
marci@1031
    85
	  tips[class_id].first=tips[class_id].last=it.i;
marci@1031
    86
	}
marci@1031
    87
      } else {
marci@1031
    88
	nodes[it.i].prev=tips[class_id].last;
marci@1031
    89
	nodes[it.i].next=-1;
marci@1031
    90
	nodes[tips[class_id].last].next=it.i;
marci@1031
    91
	tips[class_id].last=it.i;
marci@1031
    92
      }
marci@1031
    93
    }
marci@1031
    94
    void kifuz(ClassIt it, int class_id) {
marci@1031
    95
      if (tips[class_id].first==it.i) {
marci@1031
    96
	if (tips[class_id].last==it.i) {
marci@1031
    97
	  tips[class_id].first=tips[class_id].last=-1;
marci@1031
    98
	} else {
marci@1031
    99
	  tips[class_id].first=nodes[it.i].next;
marci@1031
   100
	  nodes[nodes[it.i].next].prev=-1;
marci@1031
   101
	}
marci@1031
   102
      } else {
marci@1031
   103
	if (tips[class_id].last==it.i) {
marci@1031
   104
	  tips[class_id].last=nodes[it.i].prev;
marci@1031
   105
	  nodes[nodes[it.i].prev].next=-1;
marci@1031
   106
	} else {
marci@1031
   107
	  nodes[nodes[it.i].next].prev=nodes[it.i].prev;
marci@1031
   108
	  nodes[nodes[it.i].prev].next=nodes[it.i].next;
marci@1031
   109
	}
marci@1031
   110
      }
marci@1031
   111
    }
marci@1031
   112
  public:
marci@1031
   113
    /// A new element with data \c t is pushed into the vector and into class 
marci@1031
   114
    /// \c class_id.
marci@1031
   115
    ClassIt push_back(const T& t, int class_id) { 
marci@1031
   116
      Node n;
marci@1031
   117
      n.data=t;
marci@1031
   118
      nodes.push_back(n);
marci@1031
   119
      int i=nodes.size()-1;
marci@1031
   120
      befuz(i, class_id);
marci@1031
   121
      return i;
marci@1031
   122
    }
marci@1031
   123
    /// A member is moved to an other class.
marci@1031
   124
    void set(ClassIt it, int old_class_id, int new_class_id) {
marci@1031
   125
      kifuz(it.i, old_class_id);
marci@1031
   126
      befuz(it.i, new_class_id);
marci@1031
   127
    }
marci@1031
   128
    /// Returns the data pointed by \c it.
marci@1031
   129
    T& operator[](ClassIt it) { return nodes[it.i].data; }
marci@1031
   130
    /// Returns the data pointed by \c it.
marci@1031
   131
    const T& operator[](ClassIt it) const { return nodes[it.i].data; }
marci@1031
   132
    ///.
marci@1031
   133
    class ClassIt {
marci@1031
   134
      friend class IterablePartition;
marci@1031
   135
    protected:
marci@1031
   136
      int i;
marci@1031
   137
    public:
marci@1031
   138
      /// Default constructor.
marci@1031
   139
      ClassIt() { }
marci@1031
   140
      /// This constructor constructs an iterator which points
marci@1031
   141
      /// to the member of th container indexed by the integer _i.
marci@1031
   142
      ClassIt(const int& _i) : i(_i) { }
marci@1031
   143
      /// Invalid constructor.
marci@1031
   144
      ClassIt(const Invalid&) : i(-1) { }
marci@1031
   145
    };
marci@1031
   146
    /// First member of class \c class_id.
marci@1031
   147
    ClassIt& first(ClassIt& it, int class_id) const {
marci@1031
   148
      it.i=tips[class_id].first;
marci@1031
   149
      return it;
marci@1031
   150
    }
marci@1031
   151
    /// Next member.
marci@1031
   152
    ClassIt& next(ClassIt& it) const {
marci@1031
   153
      it.i=nodes[it.i].next;
marci@1031
   154
      return it;
marci@1031
   155
    }
marci@1031
   156
    /// True iff the iterator is valid.
marci@1031
   157
    bool valid(const ClassIt& it) const { return it.i!=-1; }
marci@1031
   158
  };
marci@1031
   159
marci@1031
   160
  /*! \e
marci@1031
   161
   */
marci@1048
   162
  template <typename _Value>
marci@1031
   163
  class LPSolverBase {
marci@1031
   164
  public:
marci@1031
   165
    /// \e
marci@1048
   166
    typedef _Value Value;
marci@1048
   167
    /// \e
marci@1031
   168
    typedef IterablePartition<int>::ClassIt RowIt;
marci@1031
   169
    /// \e
marci@1031
   170
    typedef IterablePartition<int>::ClassIt ColIt;
marci@1031
   171
  protected:
marci@1031
   172
    /// \e
marci@1031
   173
    IterablePartition<int> row_iter_map;
marci@1031
   174
    /// \e
marci@1031
   175
    IterablePartition<int> col_iter_map;
marci@1031
   176
    /// \e
marci@1031
   177
    const int VALID_ID;
marci@1031
   178
    /// \e
marci@1031
   179
    const int INVALID_ID;
marci@1031
   180
  public:
marci@1031
   181
    /// \e
marci@1031
   182
    LPSolverBase() : row_iter_map(2), 
marci@1031
   183
		     col_iter_map(2), 
marci@1031
   184
		     VALID_ID(0), INVALID_ID(1) { }
marci@1031
   185
    /// \e
marci@1031
   186
    virtual ~LPSolverBase() { }
marci@1031
   187
    /// \e
marci@1031
   188
    virtual void setMinimize() = 0;
marci@1031
   189
    /// \e
marci@1031
   190
    virtual void setMaximize() = 0;
marci@1031
   191
    /// \e
marci@1031
   192
    virtual RowIt addRow() = 0;
marci@1031
   193
    /// \e
marci@1031
   194
    virtual ColIt addCol() = 0;
marci@1031
   195
    /// temporally, glpk style indexing
marci@1031
   196
    virtual void setRowCoeffs(RowIt row_it, int num, 
marci@1048
   197
			      int* indices, _Value* doubles) = 0;
marci@1048
   198
    //pair<RowIt, _Value>-bol kell megadni egy std range-et
marci@1031
   199
    /// \e
marci@1031
   200
    template <typename Begin, typename End>
marci@1031
   201
    void setRowCoeffs(RowIt row_it, Begin begin, End end) {
marci@1031
   202
      int mem_length=1+colNum();
marci@1031
   203
      int* indices = new int[mem_length];
marci@1048
   204
      _Value* doubles = new _Value[mem_length];
marci@1031
   205
      int length=0;
marci@1031
   206
      for ( ; begin!=end; ++begin) {
marci@1031
   207
	++length;
marci@1031
   208
	indices[length]=col_iter_map[begin->first];
marci@1031
   209
	doubles[length]=begin->second;
marci@1031
   210
      }
marci@1031
   211
      setRowCoeffs(row_it, length, indices, doubles);
marci@1031
   212
      delete [] indices;
marci@1031
   213
      delete [] doubles;
marci@1031
   214
    }
marci@1031
   215
    /// temporally, glpk style indexing
marci@1031
   216
    virtual void setColCoeffs(ColIt col_it, int num, 
marci@1048
   217
			      int* indices, _Value* doubles) = 0;
marci@1048
   218
    //pair<ColIt, _Value>-bol kell megadni egy std range-et
marci@1031
   219
    /// \e
marci@1031
   220
    template <typename Begin, typename End>
marci@1031
   221
    void setColCoeffs(ColIt col_it, Begin begin, End end) {
marci@1031
   222
      int mem_length=1+rowNum();
marci@1031
   223
      int* indices = new int[mem_length];
marci@1048
   224
      _Value* doubles = new _Value[mem_length];
marci@1031
   225
      int length=0;
marci@1031
   226
      for ( ; begin!=end; ++begin) {
marci@1031
   227
	++length;
marci@1031
   228
	indices[length]=row_iter_map[begin->first];
marci@1031
   229
	doubles[length]=begin->second;
marci@1031
   230
      }
marci@1031
   231
      setColCoeffs(col_it, length, indices, doubles);
marci@1031
   232
      delete [] indices;
marci@1031
   233
      delete [] doubles;
marci@1031
   234
    }
marci@1031
   235
    /// \e
marci@1031
   236
    virtual void eraseCol(const ColIt& col_it) = 0;
marci@1031
   237
    /// \e
marci@1031
   238
    virtual void eraseRow(const RowIt& row_it) = 0;
marci@1031
   239
    /// \e
marci@1031
   240
    virtual void setColBounds(const ColIt& col_it, int bound_type, 
marci@1048
   241
			      _Value lo, _Value up) =0; 
marci@1031
   242
    /// \e
marci@1048
   243
    virtual _Value getObjCoef(const ColIt& col_it) = 0;
marci@1031
   244
    /// \e
marci@1031
   245
    virtual void setRowBounds(const RowIt& row_it, int bound_type, 
marci@1048
   246
			      _Value lo, _Value up) = 0;
marci@1031
   247
    /// \e
marci@1048
   248
    virtual void setObjCoef(const ColIt& col_it, _Value obj_coef) = 0;
marci@1031
   249
    /// \e
marci@1031
   250
    virtual void solveSimplex() = 0;
marci@1031
   251
    /// \e
marci@1031
   252
    virtual void solvePrimalSimplex() = 0;
marci@1031
   253
    /// \e
marci@1031
   254
    virtual void solveDualSimplex() = 0;
marci@1031
   255
    /// \e
marci@1048
   256
    virtual _Value getPrimal(const ColIt& col_it) = 0;
marci@1031
   257
    /// \e
marci@1048
   258
    virtual _Value getObjVal() = 0;
marci@1031
   259
    /// \e
marci@1031
   260
    virtual int rowNum() const = 0;
marci@1031
   261
    /// \e
marci@1031
   262
    virtual int colNum() const = 0;
marci@1031
   263
    /// \e
marci@1031
   264
    virtual int warmUp() = 0;
marci@1031
   265
    /// \e
marci@1031
   266
    virtual void printWarmUpStatus(int i) = 0;
marci@1031
   267
    /// \e
marci@1031
   268
    virtual int getPrimalStatus() = 0;
marci@1031
   269
    /// \e
marci@1031
   270
    virtual void printPrimalStatus(int i) = 0;
marci@1031
   271
    /// \e
marci@1031
   272
    virtual int getDualStatus() = 0;
marci@1031
   273
    /// \e
marci@1031
   274
    virtual void printDualStatus(int i) = 0;
marci@1031
   275
    /// Returns the status of the slack variable assigned to row \c row_it.
marci@1031
   276
    virtual int getRowStat(const RowIt& row_it) = 0;
marci@1031
   277
    /// \e
marci@1031
   278
    virtual void printRowStatus(int i) = 0;
marci@1031
   279
    /// Returns the status of the variable assigned to column \c col_it.
marci@1031
   280
    virtual int getColStat(const ColIt& col_it) = 0;
marci@1031
   281
    /// \e
marci@1031
   282
    virtual void printColStatus(int i) = 0;
marci@1031
   283
  };
marci@1031
   284
  
marci@1048
   285
marci@1031
   286
  /// \brief Wrappers for LP solvers
marci@1031
   287
  /// 
marci@1031
   288
  /// This class implements a lemon wrapper for glpk.
marci@1031
   289
  /// Later other LP-solvers will be wrapped into lemon.
marci@1031
   290
  /// The aim of this class is to give a general surface to different 
marci@1031
   291
  /// solvers, i.e. it makes possible to write algorithms using LP's, 
marci@1031
   292
  /// in which the solver can be changed to an other one easily.
marci@1048
   293
  class LPSolverWrapper : public LPSolverBase<double> {
marci@1031
   294
  public:
marci@1048
   295
    typedef LPSolverBase<double> Parent;
marci@1031
   296
marci@1031
   297
    //   class Row {
marci@1031
   298
    //   protected:
marci@1031
   299
    //     int i;
marci@1031
   300
    //   public:
marci@1031
   301
    //     Row() { }
marci@1031
   302
    //     Row(const Invalid&) : i(0) { }
marci@1031
   303
    //     Row(const int& _i) : i(_i) { }
marci@1031
   304
    //     operator int() const { return i; }
marci@1031
   305
    //   };
marci@1031
   306
    //   class RowIt : public Row {
marci@1031
   307
    //   public:
marci@1031
   308
    //     RowIt(const Row& row) : Row(row) { }
marci@1031
   309
    //   };
marci@1031
   310
marci@1031
   311
    //   class Col {
marci@1031
   312
    //   protected:
marci@1031
   313
    //     int i;
marci@1031
   314
    //   public:
marci@1031
   315
    //     Col() { }
marci@1031
   316
    //     Col(const Invalid&) : i(0) { }
marci@1031
   317
    //     Col(const int& _i) : i(_i) { }
marci@1031
   318
    //     operator int() const { return i; }
marci@1031
   319
    //   };
marci@1031
   320
    //   class ColIt : public Col {
marci@1031
   321
    //     ColIt(const Col& col) : Col(col) { }
marci@1031
   322
    //   };
marci@1031
   323
marci@1031
   324
  public:
marci@1031
   325
    /// \e
marci@1031
   326
    LPX* lp;
marci@1031
   327
marci@1031
   328
  public:
marci@1031
   329
    /// \e
marci@1048
   330
    LPSolverWrapper() : Parent(), 
marci@1031
   331
			lp(lpx_create_prob()) {
marci@1031
   332
      lpx_set_int_parm(lp, LPX_K_DUAL, 1);
marci@1031
   333
    }
marci@1031
   334
    /// \e
marci@1031
   335
    ~LPSolverWrapper() {
marci@1031
   336
      lpx_delete_prob(lp);
marci@1031
   337
    }
marci@1031
   338
    /// \e
marci@1031
   339
    void setMinimize() { 
marci@1031
   340
      lpx_set_obj_dir(lp, LPX_MIN);
marci@1031
   341
    }
marci@1031
   342
    /// \e
marci@1031
   343
    void setMaximize() { 
marci@1031
   344
      lpx_set_obj_dir(lp, LPX_MAX);
marci@1031
   345
    }
marci@1031
   346
    /// \e
marci@1031
   347
    ColIt addCol() {
marci@1031
   348
      int i=lpx_add_cols(lp, 1);  
marci@1031
   349
      ColIt col_it;
marci@1031
   350
      col_iter_map.first(col_it, INVALID_ID);
marci@1031
   351
      if (col_iter_map.valid(col_it)) { //van hasznalhato hely
marci@1031
   352
	col_iter_map.set(col_it, INVALID_ID, VALID_ID);
marci@1031
   353
	col_iter_map[col_it]=i;
marci@1031
   354
	//col_id_to_lp_col_id[col_iter_map[col_it]]=i;
marci@1031
   355
      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
marci@1031
   356
	//col_id_to_lp_col_id.push_back(i);
marci@1031
   357
	//int j=col_id_to_lp_col_id.size()-1;
marci@1031
   358
	col_it=col_iter_map.push_back(i, VALID_ID);
marci@1031
   359
      }
marci@1031
   360
      //    edge_index_map.set(e, i);
marci@1031
   361
      //    lpx_set_col_bnds(lp, i, LPX_DB, 0.0, 1.0);
marci@1031
   362
      //    lpx_set_obj_coef(lp, i, cost[e]);    
marci@1031
   363
      return col_it;
marci@1031
   364
    }
marci@1031
   365
    /// \e
marci@1031
   366
    RowIt addRow() {
marci@1031
   367
      int i=lpx_add_rows(lp, 1);  
marci@1031
   368
      RowIt row_it;
marci@1031
   369
      row_iter_map.first(row_it, INVALID_ID);
marci@1031
   370
      if (row_iter_map.valid(row_it)) { //van hasznalhato hely
marci@1031
   371
	row_iter_map.set(row_it, INVALID_ID, VALID_ID);
marci@1031
   372
	row_iter_map[row_it]=i;
marci@1031
   373
      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
marci@1031
   374
	row_it=row_iter_map.push_back(i, VALID_ID);
marci@1031
   375
      }
marci@1031
   376
      return row_it;
marci@1031
   377
    }
marci@1031
   378
    using Parent::setRowCoeffs;
marci@1031
   379
    void setRowCoeffs(RowIt row_it, int length, 
marci@1031
   380
		      int* indices, double* doubles) {
marci@1031
   381
      lpx_set_mat_row(lp, row_iter_map[row_it], length, indices, doubles);
marci@1031
   382
    }
marci@1031
   383
    using Parent::setColCoeffs;
marci@1031
   384
    void setColCoeffs(ColIt col_it, int length, 
marci@1031
   385
		      int* indices, double* doubles) {
marci@1031
   386
      lpx_set_mat_col(lp, col_iter_map[col_it], length, indices, doubles);
marci@1031
   387
    }
marci@1031
   388
    //     //pair<RowIt, double>-bol kell megadni egy std range-et
marci@1031
   389
    //     /// \e
marci@1031
   390
    //     template <typename Begin, typename End>
marci@1031
   391
    //     void setColCoeffs(const ColIt& col_it, 
marci@1031
   392
    // 		      Begin begin, End end) {
marci@1031
   393
    //       int mem_length=1+lpx_get_num_rows(lp);
marci@1031
   394
    //       int* indices = new int[mem_length];
marci@1031
   395
    //       double* doubles = new double[mem_length];
marci@1031
   396
    //       int length=0;
marci@1031
   397
    //       for ( ; begin!=end; ++begin) {
marci@1031
   398
    // 	++length;
marci@1031
   399
    // 	indices[length]=row_iter_map[begin->first];
marci@1031
   400
    // 	doubles[length]=begin->second;
marci@1031
   401
    //       }
marci@1031
   402
    //       lpx_set_mat_col(lp, col_iter_map[col_it], length, indices, doubles);
marci@1031
   403
    //       delete [] indices;
marci@1031
   404
    //       delete [] doubles;
marci@1031
   405
    //     }
marci@1031
   406
    //     //pair<ColIt, double>-bol kell megadni egy std range-et
marci@1031
   407
    //     /// \e
marci@1031
   408
    //     template <typename Begin, typename End>
marci@1031
   409
    //     void setRowCoeffs(const RowIt& row_it, 
marci@1031
   410
    // 		      Begin begin, End end) {
marci@1031
   411
    //       int mem_length=1+lpx_get_num_cols(lp);
marci@1031
   412
    //       int* indices = new int[mem_length];
marci@1031
   413
    //       double* doubles = new double[mem_length];
marci@1031
   414
    //       int length=0;
marci@1031
   415
    //       for ( ; begin!=end; ++begin) {
marci@1031
   416
    // 	++length;
marci@1031
   417
    // 	indices[length]=col_iter_map[begin->first];
marci@1031
   418
    // 	doubles[length]=begin->second;
marci@1031
   419
    //       }
marci@1031
   420
    //       lpx_set_mat_row(lp, row_iter_map[row_it], length, indices, doubles);
marci@1031
   421
    //       delete [] indices;
marci@1031
   422
    //       delete [] doubles;
marci@1031
   423
    //     }
marci@1031
   424
    /// \e
marci@1031
   425
    void eraseCol(const ColIt& col_it) {
marci@1031
   426
      col_iter_map.set(col_it, VALID_ID, INVALID_ID);
marci@1031
   427
      int cols[2];
marci@1031
   428
      cols[1]=col_iter_map[col_it];
marci@1031
   429
      lpx_del_cols(lp, 1, cols);
marci@1031
   430
      col_iter_map[col_it]=0; //glpk specifikus
marci@1031
   431
      ColIt it;
marci@1031
   432
      for (col_iter_map.first(it, VALID_ID); 
marci@1031
   433
	   col_iter_map.valid(it); col_iter_map.next(it)) {
marci@1031
   434
	if (col_iter_map[it]>cols[1]) --col_iter_map[it];
marci@1031
   435
      }
marci@1031
   436
    }
marci@1031
   437
    /// \e
marci@1031
   438
    void eraseRow(const RowIt& row_it) {
marci@1031
   439
      row_iter_map.set(row_it, VALID_ID, INVALID_ID);
marci@1031
   440
      int rows[2];
marci@1031
   441
      rows[1]=row_iter_map[row_it];
marci@1031
   442
      lpx_del_rows(lp, 1, rows);
marci@1031
   443
      row_iter_map[row_it]=0; //glpk specifikus
marci@1031
   444
      RowIt it;
marci@1031
   445
      for (row_iter_map.first(it, VALID_ID); 
marci@1031
   446
	   row_iter_map.valid(it); row_iter_map.next(it)) {
marci@1031
   447
	if (row_iter_map[it]>rows[1]) --row_iter_map[it];
marci@1031
   448
      }
marci@1031
   449
    }
marci@1031
   450
    /// \e
marci@1031
   451
    void setColBounds(const ColIt& col_it, int bound_type, 
marci@1031
   452
		      double lo, double up) {
marci@1031
   453
      lpx_set_col_bnds(lp, col_iter_map[col_it], bound_type, lo, up);
marci@1031
   454
    }
marci@1031
   455
    /// \e
marci@1031
   456
    double getObjCoef(const ColIt& col_it) { 
marci@1031
   457
      return lpx_get_obj_coef(lp, col_iter_map[col_it]);
marci@1031
   458
    }
marci@1031
   459
    /// \e
marci@1031
   460
    void setRowBounds(const RowIt& row_it, int bound_type, 
marci@1031
   461
		      double lo, double up) {
marci@1031
   462
      lpx_set_row_bnds(lp, row_iter_map[row_it], bound_type, lo, up);
marci@1031
   463
    }
marci@1031
   464
    /// \e
marci@1031
   465
    void setObjCoef(const ColIt& col_it, double obj_coef) { 
marci@1031
   466
      lpx_set_obj_coef(lp, col_iter_map[col_it], obj_coef);
marci@1031
   467
    }
marci@1031
   468
    /// \e
marci@1031
   469
    void solveSimplex() { lpx_simplex(lp); }
marci@1031
   470
    /// \e
marci@1031
   471
    void solvePrimalSimplex() { lpx_simplex(lp); }
marci@1031
   472
    /// \e
marci@1031
   473
    void solveDualSimplex() { lpx_simplex(lp); }
marci@1031
   474
    /// \e
marci@1031
   475
    double getPrimal(const ColIt& col_it) {
marci@1031
   476
      return lpx_get_col_prim(lp, col_iter_map[col_it]);
marci@1031
   477
    }
marci@1031
   478
    /// \e
marci@1031
   479
    double getObjVal() { return lpx_get_obj_val(lp); }
marci@1031
   480
    /// \e
marci@1031
   481
    int rowNum() const { return lpx_get_num_rows(lp); }
marci@1031
   482
    /// \e
marci@1031
   483
    int colNum() const { return lpx_get_num_cols(lp); }
marci@1031
   484
    /// \e
marci@1031
   485
    int warmUp() { return lpx_warm_up(lp); }
marci@1031
   486
    /// \e
marci@1031
   487
    void printWarmUpStatus(int i) {
marci@1031
   488
      switch (i) {
marci@1031
   489
      case LPX_E_OK: cout << "LPX_E_OK" << endl; break;
marci@1031
   490
      case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break;	
marci@1031
   491
      case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break;
marci@1031
   492
      case LPX_E_SING: cout << "LPX_E_SING" << endl; break;
marci@1031
   493
      }
marci@1031
   494
    }
marci@1031
   495
    /// \e
marci@1031
   496
    int getPrimalStatus() { return lpx_get_prim_stat(lp); }
marci@1031
   497
    /// \e
marci@1031
   498
    void printPrimalStatus(int i) {
marci@1031
   499
      switch (i) {
marci@1031
   500
      case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break;
marci@1031
   501
      case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break;	
marci@1031
   502
      case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break;
marci@1031
   503
      case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break;
marci@1031
   504
      }
marci@1031
   505
    }
marci@1031
   506
    /// \e
marci@1031
   507
    int getDualStatus() { return lpx_get_dual_stat(lp); }
marci@1031
   508
    /// \e
marci@1031
   509
    void printDualStatus(int i) {
marci@1031
   510
      switch (i) {
marci@1031
   511
      case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break;
marci@1031
   512
      case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;	
marci@1031
   513
      case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
marci@1031
   514
      case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
marci@1031
   515
      }
marci@1031
   516
    }
marci@1031
   517
    /// Returns the status of the slack variable assigned to row \c row_it.
marci@1031
   518
    int getRowStat(const RowIt& row_it) { 
marci@1031
   519
      return lpx_get_row_stat(lp, row_iter_map[row_it]); 
marci@1031
   520
    }
marci@1031
   521
    /// \e
marci@1031
   522
    void printRowStatus(int i) {
marci@1031
   523
      switch (i) {
marci@1031
   524
      case LPX_BS: cout << "LPX_BS" << endl; break;
marci@1031
   525
      case LPX_NL: cout << "LPX_NL" << endl; break;	
marci@1031
   526
      case LPX_NU: cout << "LPX_NU" << endl; break;
marci@1031
   527
      case LPX_NF: cout << "LPX_NF" << endl; break;
marci@1031
   528
      case LPX_NS: cout << "LPX_NS" << endl; break;
marci@1031
   529
      }
marci@1031
   530
    }
marci@1031
   531
    /// Returns the status of the variable assigned to column \c col_it.
marci@1031
   532
    int getColStat(const ColIt& col_it) { 
marci@1031
   533
      return lpx_get_col_stat(lp, col_iter_map[col_it]); 
marci@1031
   534
    }
marci@1031
   535
    /// \e
marci@1031
   536
    void printColStatus(int i) {
marci@1031
   537
      switch (i) {
marci@1031
   538
      case LPX_BS: cout << "LPX_BS" << endl; break;
marci@1031
   539
      case LPX_NL: cout << "LPX_NL" << endl; break;	
marci@1031
   540
      case LPX_NU: cout << "LPX_NU" << endl; break;
marci@1031
   541
      case LPX_NF: cout << "LPX_NF" << endl; break;
marci@1031
   542
      case LPX_NS: cout << "LPX_NS" << endl; break;
marci@1031
   543
      }
marci@1031
   544
    }
marci@1031
   545
  };
marci@1031
   546
  
marci@1031
   547
  /// @}
marci@1031
   548
marci@1031
   549
} //namespace lemon
marci@1031
   550
marci@1031
   551
#endif //LEMON_LP_SOLVER_WRAPPER_H