src/work/marci/lp/lp_solver_wrapper_3.h
author alpar
Fri, 28 Jan 2005 08:53:48 +0000
changeset 1101 9286569c3749
parent 1099 91a8ee9d088d
child 1104 23a54f889272
permissions -rw-r--r--
Wrap a long line
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@1097
    11
#include <iostream>
marci@1097
    12
#include <map>
marci@1031
    13
// #include <stdio>
marci@1031
    14
//#include <stdlib>
marci@1031
    15
extern "C" {
marci@1031
    16
#include "glpk.h"
marci@1031
    17
}
marci@1031
    18
marci@1031
    19
#include <iostream>
marci@1031
    20
#include <vector>
marci@1031
    21
#include <string>
marci@1031
    22
#include <list>
marci@1031
    23
#include <memory>
marci@1031
    24
#include <utility>
marci@1031
    25
marci@1031
    26
//#include <sage_graph.h>
marci@1031
    27
//#include <lemon/list_graph.h>
marci@1031
    28
//#include <lemon/graph_wrapper.h>
marci@1031
    29
#include <lemon/invalid.h>
marci@1099
    30
#include <expression.h>
marci@1031
    31
//#include <bfs_dfs.h>
marci@1031
    32
//#include <stp.h>
marci@1031
    33
//#include <lemon/max_flow.h>
marci@1031
    34
//#include <augmenting_flow.h>
marci@1031
    35
//#include <iter_map.h>
marci@1031
    36
marci@1031
    37
using std::cout;
marci@1031
    38
using std::cin;
marci@1031
    39
using std::endl;
marci@1031
    40
marci@1031
    41
namespace lemon {
marci@1031
    42
  
marci@1031
    43
  /// \addtogroup misc
marci@1031
    44
  /// @{
marci@1031
    45
marci@1031
    46
  /// \brief A partitioned vector with iterable classes.
marci@1031
    47
  ///
marci@1031
    48
  /// This class implements a container in which the data is stored in an 
marci@1031
    49
  /// stl vector, the range is partitioned into sets and each set is 
marci@1031
    50
  /// doubly linked in a list. 
marci@1031
    51
  /// That is, each class is iterable by lemon iterators, and any member of 
marci@1031
    52
  /// the vector can bo moved to an other class.
marci@1031
    53
  template <typename T>
marci@1031
    54
  class IterablePartition {
marci@1031
    55
  protected:
marci@1031
    56
    struct Node {
marci@1031
    57
      T data;
marci@1031
    58
      int prev; //invalid az -1
marci@1031
    59
      int next; 
marci@1031
    60
    };
marci@1031
    61
    std::vector<Node> nodes;
marci@1031
    62
    struct Tip {
marci@1031
    63
      int first;
marci@1031
    64
      int last;
marci@1031
    65
    };
marci@1031
    66
    std::vector<Tip> tips;
marci@1031
    67
  public:
marci@1031
    68
    /// The classes are indexed by integers from \c 0 to \c classNum()-1.
marci@1031
    69
    int classNum() const { return tips.size(); }
marci@1031
    70
    /// This lemon style iterator iterates through a class. 
marci@1031
    71
    class ClassIt;
marci@1031
    72
    /// Constructor. The number of classes is to be given which is fixed 
marci@1031
    73
    /// over the life of the container. 
marci@1031
    74
    /// The partition classes are indexed from 0 to class_num-1. 
marci@1031
    75
    IterablePartition(int class_num) { 
marci@1031
    76
      for (int i=0; i<class_num; ++i) {
marci@1031
    77
	Tip t;
marci@1031
    78
	t.first=t.last=-1;
marci@1031
    79
	tips.push_back(t);
marci@1031
    80
      }
marci@1031
    81
    }
marci@1031
    82
  protected:
marci@1031
    83
    void befuz(ClassIt it, int class_id) {
marci@1031
    84
      if (tips[class_id].first==-1) {
marci@1031
    85
	if (tips[class_id].last==-1) {
marci@1031
    86
	  nodes[it.i].prev=nodes[it.i].next=-1;
marci@1031
    87
	  tips[class_id].first=tips[class_id].last=it.i;
marci@1031
    88
	}
marci@1031
    89
      } else {
marci@1031
    90
	nodes[it.i].prev=tips[class_id].last;
marci@1031
    91
	nodes[it.i].next=-1;
marci@1031
    92
	nodes[tips[class_id].last].next=it.i;
marci@1031
    93
	tips[class_id].last=it.i;
marci@1031
    94
      }
marci@1031
    95
    }
marci@1031
    96
    void kifuz(ClassIt it, int class_id) {
marci@1031
    97
      if (tips[class_id].first==it.i) {
marci@1031
    98
	if (tips[class_id].last==it.i) {
marci@1031
    99
	  tips[class_id].first=tips[class_id].last=-1;
marci@1031
   100
	} else {
marci@1031
   101
	  tips[class_id].first=nodes[it.i].next;
marci@1031
   102
	  nodes[nodes[it.i].next].prev=-1;
marci@1031
   103
	}
marci@1031
   104
      } else {
marci@1031
   105
	if (tips[class_id].last==it.i) {
marci@1031
   106
	  tips[class_id].last=nodes[it.i].prev;
marci@1031
   107
	  nodes[nodes[it.i].prev].next=-1;
marci@1031
   108
	} else {
marci@1031
   109
	  nodes[nodes[it.i].next].prev=nodes[it.i].prev;
marci@1031
   110
	  nodes[nodes[it.i].prev].next=nodes[it.i].next;
marci@1031
   111
	}
marci@1031
   112
      }
marci@1031
   113
    }
marci@1031
   114
  public:
marci@1031
   115
    /// A new element with data \c t is pushed into the vector and into class 
marci@1031
   116
    /// \c class_id.
marci@1031
   117
    ClassIt push_back(const T& t, int class_id) { 
marci@1031
   118
      Node n;
marci@1031
   119
      n.data=t;
marci@1031
   120
      nodes.push_back(n);
marci@1031
   121
      int i=nodes.size()-1;
marci@1031
   122
      befuz(i, class_id);
marci@1031
   123
      return i;
marci@1031
   124
    }
marci@1031
   125
    /// A member is moved to an other class.
marci@1031
   126
    void set(ClassIt it, int old_class_id, int new_class_id) {
marci@1031
   127
      kifuz(it.i, old_class_id);
marci@1031
   128
      befuz(it.i, new_class_id);
marci@1031
   129
    }
marci@1031
   130
    /// Returns the data pointed by \c it.
marci@1031
   131
    T& operator[](ClassIt it) { return nodes[it.i].data; }
marci@1031
   132
    /// Returns the data pointed by \c it.
marci@1031
   133
    const T& operator[](ClassIt it) const { return nodes[it.i].data; }
marci@1031
   134
    ///.
marci@1031
   135
    class ClassIt {
marci@1031
   136
      friend class IterablePartition;
marci@1031
   137
    protected:
marci@1031
   138
      int i;
marci@1031
   139
    public:
marci@1031
   140
      /// Default constructor.
marci@1031
   141
      ClassIt() { }
marci@1031
   142
      /// This constructor constructs an iterator which points
marci@1031
   143
      /// to the member of th container indexed by the integer _i.
marci@1031
   144
      ClassIt(const int& _i) : i(_i) { }
marci@1031
   145
      /// Invalid constructor.
marci@1031
   146
      ClassIt(const Invalid&) : i(-1) { }
marci@1099
   147
      friend bool operator<(const ClassIt& x, const ClassIt& y);
marci@1099
   148
      friend std::ostream& operator<<(std::ostream& os, 
marci@1099
   149
				      const ClassIt& it);
marci@1031
   150
    };
marci@1099
   151
    friend bool operator<(const ClassIt& x, const ClassIt& y) {
marci@1099
   152
      return (x.i < y.i);
marci@1099
   153
    }
marci@1099
   154
    friend std::ostream& operator<<(std::ostream& os, 
marci@1099
   155
				    const ClassIt& it) {
marci@1099
   156
      os << it.i;
marci@1099
   157
      return os;
marci@1099
   158
    }
marci@1031
   159
    /// First member of class \c class_id.
marci@1031
   160
    ClassIt& first(ClassIt& it, int class_id) const {
marci@1031
   161
      it.i=tips[class_id].first;
marci@1031
   162
      return it;
marci@1031
   163
    }
marci@1031
   164
    /// Next member.
marci@1031
   165
    ClassIt& next(ClassIt& it) const {
marci@1031
   166
      it.i=nodes[it.i].next;
marci@1031
   167
      return it;
marci@1031
   168
    }
marci@1031
   169
    /// True iff the iterator is valid.
marci@1031
   170
    bool valid(const ClassIt& it) const { return it.i!=-1; }
marci@1031
   171
  };
marci@1031
   172
marci@1097
   173
marci@1031
   174
  /*! \e
alpar@1100
   175
alpar@1100
   176
  \todo A[x,y]-t cserel. Jobboldal, baloldal csere.
alpar@1100
   177
  \todo LEKERDEZESEK!!!
alpar@1100
   178
  \todo DOKSI!!!! Doxygen group!!!
alpar@1100
   179
marci@1031
   180
   */
marci@1048
   181
  template <typename _Value>
marci@1031
   182
  class LPSolverBase {
marci@1031
   183
  public:
marci@1031
   184
    /// \e
marci@1048
   185
    typedef _Value Value;
marci@1048
   186
    /// \e
marci@1031
   187
    typedef IterablePartition<int>::ClassIt RowIt;
marci@1031
   188
    /// \e
marci@1031
   189
    typedef IterablePartition<int>::ClassIt ColIt;
marci@1074
   190
  public:
marci@1031
   191
    /// \e
marci@1031
   192
    IterablePartition<int> row_iter_map;
marci@1031
   193
    /// \e
marci@1031
   194
    IterablePartition<int> col_iter_map;
marci@1031
   195
    /// \e
marci@1074
   196
    const int VALID_CLASS;
marci@1031
   197
    /// \e
marci@1074
   198
    const int INVALID_CLASS;
marci@1031
   199
  public:
marci@1031
   200
    /// \e
marci@1031
   201
    LPSolverBase() : row_iter_map(2), 
marci@1031
   202
		     col_iter_map(2), 
marci@1074
   203
		     VALID_CLASS(0), INVALID_CLASS(1) { }
marci@1031
   204
    /// \e
marci@1031
   205
    virtual ~LPSolverBase() { }
marci@1081
   206
marci@1081
   207
    //MATRIX INDEPEDENT MANIPULATING FUNCTIONS
marci@1081
   208
marci@1081
   209
  public:
marci@1031
   210
    /// \e
marci@1031
   211
    virtual void setMinimize() = 0;
marci@1031
   212
    /// \e
marci@1031
   213
    virtual void setMaximize() = 0;
marci@1081
   214
marci@1081
   215
    //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS
marci@1081
   216
marci@1074
   217
  protected:
marci@1031
   218
    /// \e
marci@1074
   219
    virtual int _addRow() = 0;
marci@1031
   220
    /// \e
marci@1074
   221
    virtual int _addCol() = 0;
marci@1081
   222
    /// \e
marci@1081
   223
    virtual void _setRowCoeffs(int i, 
marci@1081
   224
			       std::vector<std::pair<int, double> > coeffs) = 0;
marci@1081
   225
    /// \e
marci@1081
   226
    virtual void _setColCoeffs(int i, 
marci@1081
   227
			       std::vector<std::pair<int, double> > coeffs) = 0;
marci@1081
   228
    /// \e
marci@1081
   229
    virtual void _eraseCol(int i) = 0;
marci@1081
   230
    /// \e
marci@1081
   231
    virtual void _eraseRow(int i) = 0;
marci@1081
   232
  public:
marci@1081
   233
    /// \e
marci@1081
   234
    enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
marci@1081
   235
  protected:
marci@1081
   236
    /// \e
marci@1081
   237
    virtual void _setColBounds(int i, Bound bound, 
marci@1081
   238
			       _Value lo, _Value up) = 0; 
marci@1081
   239
    /// \e
marci@1081
   240
    virtual void _setRowBounds(int i, Bound bound, 
marci@1081
   241
			       _Value lo, _Value up) = 0; 
marci@1081
   242
    /// \e
marci@1081
   243
    virtual void _setObjCoef(int i, _Value obj_coef) = 0;
marci@1081
   244
    /// \e
marci@1081
   245
    virtual _Value _getObjCoef(int i) = 0;
marci@1081
   246
marci@1081
   247
    //LOW LEVEL, SOLUTION RETRIEVING FUNCTIONS
marci@1081
   248
marci@1081
   249
  protected:
marci@1081
   250
    virtual _Value _getPrimal(int i) = 0;
marci@1081
   251
marci@1081
   252
    //HIGH LEVEL INTERFACE, MATRIX MANIPULATING FUNTIONS
marci@1081
   253
marci@1074
   254
  public:
marci@1074
   255
    /// \e
marci@1074
   256
    RowIt addRow() {
marci@1074
   257
      int i=_addRow(); 
marci@1074
   258
      RowIt row_it;
marci@1074
   259
      row_iter_map.first(row_it, INVALID_CLASS);
marci@1074
   260
      if (row_iter_map.valid(row_it)) { //van hasznalhato hely
marci@1074
   261
	row_iter_map.set(row_it, INVALID_CLASS, VALID_CLASS);
marci@1074
   262
	row_iter_map[row_it]=i;
marci@1074
   263
      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
marci@1074
   264
	row_it=row_iter_map.push_back(i, VALID_CLASS);
marci@1074
   265
      }
marci@1074
   266
      return row_it;
marci@1074
   267
    }
marci@1074
   268
    /// \e
marci@1074
   269
    ColIt addCol() {
marci@1074
   270
      int i=_addCol();  
marci@1074
   271
      ColIt col_it;
marci@1074
   272
      col_iter_map.first(col_it, INVALID_CLASS);
marci@1074
   273
      if (col_iter_map.valid(col_it)) { //van hasznalhato hely
marci@1074
   274
	col_iter_map.set(col_it, INVALID_CLASS, VALID_CLASS);
marci@1074
   275
	col_iter_map[col_it]=i;
marci@1074
   276
      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
marci@1074
   277
	col_it=col_iter_map.push_back(i, VALID_CLASS);
marci@1074
   278
      }
marci@1074
   279
      return col_it;
marci@1074
   280
    }
marci@1074
   281
    /// \e
marci@1031
   282
    template <typename Begin, typename End>
marci@1031
   283
    void setRowCoeffs(RowIt row_it, Begin begin, End end) {
marci@1074
   284
      std::vector<std::pair<int, double> > coeffs;
marci@1031
   285
      for ( ; begin!=end; ++begin) {
marci@1074
   286
	coeffs.push_back(std::
marci@1074
   287
			 make_pair(col_iter_map[begin->first], begin->second));
marci@1031
   288
      }
marci@1081
   289
      _setRowCoeffs(row_iter_map[row_it], coeffs);
marci@1031
   290
    }
marci@1031
   291
    /// \e
marci@1031
   292
    template <typename Begin, typename End>
marci@1031
   293
    void setColCoeffs(ColIt col_it, Begin begin, End end) {
marci@1074
   294
      std::vector<std::pair<int, double> > coeffs;
marci@1031
   295
      for ( ; begin!=end; ++begin) {
marci@1074
   296
	coeffs.push_back(std::
marci@1074
   297
			 make_pair(row_iter_map[begin->first], begin->second));
marci@1031
   298
      }
marci@1081
   299
      _setColCoeffs(col_iter_map[col_it], coeffs);
marci@1074
   300
    }
marci@1074
   301
    /// \e
marci@1074
   302
    void eraseCol(const ColIt& col_it) {
marci@1074
   303
      col_iter_map.set(col_it, VALID_CLASS, INVALID_CLASS);
marci@1074
   304
      int cols[2];
marci@1074
   305
      cols[1]=col_iter_map[col_it];
marci@1074
   306
      _eraseCol(cols[1]);
marci@1074
   307
      col_iter_map[col_it]=0; //glpk specifikus, de kell ez??
marci@1074
   308
      ColIt it;
marci@1074
   309
      for (col_iter_map.first(it, VALID_CLASS); 
marci@1074
   310
	   col_iter_map.valid(it); col_iter_map.next(it)) {
marci@1074
   311
	if (col_iter_map[it]>cols[1]) --col_iter_map[it];
marci@1074
   312
      }
marci@1031
   313
    }
marci@1031
   314
    /// \e
marci@1074
   315
    void eraseRow(const RowIt& row_it) {
marci@1074
   316
      row_iter_map.set(row_it, VALID_CLASS, INVALID_CLASS);
marci@1074
   317
      int rows[2];
marci@1074
   318
      rows[1]=row_iter_map[row_it];
marci@1074
   319
      _eraseRow(rows[1]);
marci@1074
   320
      row_iter_map[row_it]=0; //glpk specifikus, de kell ez??
marci@1074
   321
      RowIt it;
marci@1074
   322
      for (row_iter_map.first(it, VALID_CLASS); 
marci@1074
   323
	   row_iter_map.valid(it); row_iter_map.next(it)) {
marci@1074
   324
	if (row_iter_map[it]>rows[1]) --row_iter_map[it];
marci@1074
   325
      }
marci@1074
   326
    }
marci@1031
   327
    /// \e
marci@1081
   328
    void setColBounds(const ColIt& col_it, Bound bound, 
marci@1081
   329
		      _Value lo, _Value up) {
marci@1081
   330
      _setColBounds(col_iter_map[col_it], bound, lo, up);
marci@1081
   331
    }
marci@1031
   332
    /// \e
marci@1081
   333
    void setRowBounds(const RowIt& row_it, Bound bound, 
marci@1081
   334
		      _Value lo, _Value up) {
marci@1081
   335
      _setRowBounds(row_iter_map[row_it], bound, lo, up);
marci@1081
   336
    }
marci@1031
   337
    /// \e
marci@1081
   338
    void setObjCoef(const ColIt& col_it, _Value obj_coef) {
marci@1081
   339
      _setObjCoef(col_iter_map[col_it], obj_coef);
marci@1081
   340
    }
marci@1031
   341
    /// \e
marci@1081
   342
    _Value getObjCoef(const ColIt& col_it) {
marci@1081
   343
      return _getObjCoef(col_iter_map[col_it]);
marci@1081
   344
    }
marci@1081
   345
marci@1099
   346
    //MOST HIGH LEVEL, USER FRIEND FUNCTIONS
marci@1099
   347
marci@1099
   348
    /// \e
marci@1099
   349
    typedef Expr<ColIt, _Value> Expression;
marci@1099
   350
    /// \e
marci@1099
   351
    typedef Expr<RowIt, _Value> DualExpression;
marci@1099
   352
    /// \e
marci@1099
   353
    void setRowCoeffs(RowIt row_it, const Expression& expr) {
marci@1099
   354
      std::vector<std::pair<int, _Value> > row_coeffs;
marci@1099
   355
      for(typename Expression::Data::const_iterator i=expr.data.begin(); 
marci@1099
   356
	  i!=expr.data.end(); ++i) {
marci@1099
   357
	row_coeffs.push_back(std::make_pair
marci@1099
   358
			     (col_iter_map[(*i).first], (*i).second));
marci@1099
   359
      }
marci@1099
   360
      _setRowCoeffs(row_iter_map[row_it], row_coeffs);
marci@1099
   361
    }
marci@1099
   362
    /// \e
marci@1099
   363
    void setColCoeffs(ColIt col_it, const DualExpression& expr) {
marci@1099
   364
      std::vector<std::pair<int, _Value> > col_coeffs;
marci@1099
   365
      for(typename DualExpression::Data::const_iterator i=expr.data.begin(); 
marci@1099
   366
	  i!=expr.data.end(); ++i) {
marci@1099
   367
	col_coeffs.push_back(std::make_pair
marci@1099
   368
			     (row_iter_map[(*i).first], (*i).second));
marci@1099
   369
      }
marci@1099
   370
      _setColCoeffs(col_iter_map[col_it], col_coeffs);
marci@1099
   371
    }
marci@1099
   372
    /// \e
marci@1099
   373
    void setObjCoeffs(const Expression& expr) {
marci@1099
   374
      for(typename Expression::Data::const_iterator i=expr.data.begin(); 
marci@1099
   375
	  i!=expr.data.end(); ++i) {
marci@1099
   376
	setObjCoef((*i).first, (*i).second);
marci@1099
   377
      }
marci@1099
   378
    }
marci@1081
   379
    //SOLVER FUNCTIONS
marci@1081
   380
marci@1031
   381
    /// \e
marci@1031
   382
    virtual void solveSimplex() = 0;
marci@1031
   383
    /// \e
marci@1031
   384
    virtual void solvePrimalSimplex() = 0;
marci@1031
   385
    /// \e
marci@1031
   386
    virtual void solveDualSimplex() = 0;
marci@1031
   387
    /// \e
marci@1081
   388
marci@1081
   389
    //HIGH LEVEL, SOLUTION RETRIEVING FUNCTIONS
marci@1081
   390
marci@1081
   391
  public:
marci@1081
   392
    _Value getPrimal(const ColIt& col_it) {
marci@1081
   393
      return _getPrimal(col_iter_map[col_it]);
marci@1081
   394
    }
marci@1031
   395
    /// \e
marci@1048
   396
    virtual _Value getObjVal() = 0;
marci@1081
   397
marci@1081
   398
    //OTHER FUNCTIONS
marci@1081
   399
marci@1031
   400
    /// \e
marci@1031
   401
    virtual int rowNum() const = 0;
marci@1031
   402
    /// \e
marci@1031
   403
    virtual int colNum() const = 0;
marci@1031
   404
    /// \e
marci@1031
   405
    virtual int warmUp() = 0;
marci@1031
   406
    /// \e
marci@1031
   407
    virtual void printWarmUpStatus(int i) = 0;
marci@1031
   408
    /// \e
marci@1031
   409
    virtual int getPrimalStatus() = 0;
marci@1031
   410
    /// \e
marci@1031
   411
    virtual void printPrimalStatus(int i) = 0;
marci@1031
   412
    /// \e
marci@1031
   413
    virtual int getDualStatus() = 0;
marci@1031
   414
    /// \e
marci@1031
   415
    virtual void printDualStatus(int i) = 0;
marci@1031
   416
    /// Returns the status of the slack variable assigned to row \c row_it.
marci@1031
   417
    virtual int getRowStat(const RowIt& row_it) = 0;
marci@1031
   418
    /// \e
marci@1031
   419
    virtual void printRowStatus(int i) = 0;
marci@1031
   420
    /// Returns the status of the variable assigned to column \c col_it.
marci@1031
   421
    virtual int getColStat(const ColIt& col_it) = 0;
marci@1031
   422
    /// \e
marci@1031
   423
    virtual void printColStatus(int i) = 0;
marci@1031
   424
  };
marci@1031
   425
  
marci@1048
   426
marci@1031
   427
  /// \brief Wrappers for LP solvers
marci@1031
   428
  /// 
marci@1031
   429
  /// This class implements a lemon wrapper for glpk.
marci@1031
   430
  /// Later other LP-solvers will be wrapped into lemon.
marci@1031
   431
  /// The aim of this class is to give a general surface to different 
marci@1031
   432
  /// solvers, i.e. it makes possible to write algorithms using LP's, 
marci@1031
   433
  /// in which the solver can be changed to an other one easily.
marci@1081
   434
  class LPGLPK : public LPSolverBase<double> {
marci@1031
   435
  public:
marci@1048
   436
    typedef LPSolverBase<double> Parent;
marci@1031
   437
marci@1031
   438
  public:
marci@1031
   439
    /// \e
marci@1031
   440
    LPX* lp;
marci@1031
   441
marci@1031
   442
  public:
marci@1031
   443
    /// \e
marci@1081
   444
    LPGLPK() : Parent(), 
marci@1031
   445
			lp(lpx_create_prob()) {
marci@1031
   446
      lpx_set_int_parm(lp, LPX_K_DUAL, 1);
marci@1031
   447
    }
marci@1031
   448
    /// \e
marci@1081
   449
    ~LPGLPK() {
marci@1031
   450
      lpx_delete_prob(lp);
marci@1031
   451
    }
marci@1081
   452
marci@1081
   453
    //MATRIX INDEPEDENT MANIPULATING FUNCTIONS
marci@1081
   454
marci@1031
   455
    /// \e
marci@1031
   456
    void setMinimize() { 
marci@1031
   457
      lpx_set_obj_dir(lp, LPX_MIN);
marci@1031
   458
    }
marci@1031
   459
    /// \e
marci@1031
   460
    void setMaximize() { 
marci@1031
   461
      lpx_set_obj_dir(lp, LPX_MAX);
marci@1031
   462
    }
marci@1081
   463
marci@1081
   464
    //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS
marci@1081
   465
marci@1074
   466
  protected:
marci@1031
   467
    /// \e
marci@1074
   468
    int _addCol() { 
marci@1074
   469
      return lpx_add_cols(lp, 1);
marci@1031
   470
    }
marci@1031
   471
    /// \e
marci@1074
   472
    int _addRow() { 
marci@1074
   473
      return lpx_add_rows(lp, 1);
marci@1074
   474
    }
marci@1074
   475
    /// \e
marci@1081
   476
    virtual void _setRowCoeffs(int i, 
marci@1081
   477
			       std::vector<std::pair<int, double> > coeffs) {
marci@1074
   478
      int mem_length=1+colNum();
marci@1074
   479
      int* indices = new int[mem_length];
marci@1074
   480
      double* doubles = new double[mem_length];
marci@1074
   481
      int length=0;
marci@1074
   482
      for (std::vector<std::pair<int, double> >::
marci@1074
   483
	     const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
marci@1074
   484
	++length;
marci@1074
   485
	indices[length]=it->first;
marci@1074
   486
	doubles[length]=it->second;
marci@1081
   487
// 	std::cout << "  " << indices[length] << " " 
marci@1081
   488
// 		  << doubles[length] << std::endl;
marci@1031
   489
      }
marci@1081
   490
//      std::cout << i << " " << length << std::endl;
marci@1074
   491
      lpx_set_mat_row(lp, i, length, indices, doubles);
marci@1074
   492
      delete [] indices;
marci@1074
   493
      delete [] doubles;
marci@1031
   494
    }
marci@1074
   495
    /// \e
marci@1081
   496
    virtual void _setColCoeffs(int i, 
marci@1081
   497
			       std::vector<std::pair<int, double> > coeffs) {
marci@1074
   498
      int mem_length=1+rowNum();
marci@1074
   499
      int* indices = new int[mem_length];
marci@1074
   500
      double* doubles = new double[mem_length];
marci@1074
   501
      int length=0;
marci@1074
   502
      for (std::vector<std::pair<int, double> >::
marci@1074
   503
	     const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
marci@1074
   504
	++length;
marci@1074
   505
	indices[length]=it->first;
marci@1074
   506
	doubles[length]=it->second;
marci@1074
   507
      }
marci@1074
   508
      lpx_set_mat_col(lp, i, length, indices, doubles);
marci@1074
   509
      delete [] indices;
marci@1074
   510
      delete [] doubles;
marci@1031
   511
    }
marci@1031
   512
    /// \e
marci@1074
   513
    virtual void _eraseCol(int i) {
marci@1031
   514
      int cols[2];
marci@1074
   515
      cols[1]=i;
marci@1031
   516
      lpx_del_cols(lp, 1, cols);
marci@1031
   517
    }
marci@1074
   518
    virtual void _eraseRow(int i) {
marci@1031
   519
      int rows[2];
marci@1074
   520
      rows[1]=i;
marci@1031
   521
      lpx_del_rows(lp, 1, rows);
marci@1031
   522
    }
marci@1081
   523
    virtual void _setColBounds(int i, Bound bound, 
marci@1081
   524
			       double lo, double up) {
marci@1081
   525
      switch (bound) {
marci@1081
   526
      case FREE:
marci@1081
   527
	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
marci@1081
   528
	break;
marci@1081
   529
      case LOWER:
marci@1081
   530
	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
marci@1081
   531
	break;
marci@1081
   532
      case UPPER:
marci@1081
   533
	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
marci@1081
   534
	break;
marci@1081
   535
      case DOUBLE:
marci@1081
   536
	lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
marci@1081
   537
	break;
marci@1081
   538
      case FIXED:
marci@1081
   539
	lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
marci@1081
   540
	break;
marci@1081
   541
      }
marci@1081
   542
    } 
marci@1081
   543
    virtual void _setRowBounds(int i, Bound bound, 
marci@1081
   544
			       double lo, double up) {
marci@1081
   545
      switch (bound) {
marci@1081
   546
      case FREE:
marci@1081
   547
	lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
marci@1081
   548
	break;
marci@1081
   549
      case LOWER:
marci@1081
   550
	lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
marci@1081
   551
	break;
marci@1081
   552
      case UPPER:
marci@1081
   553
	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
marci@1081
   554
	break;
marci@1081
   555
      case DOUBLE:
marci@1081
   556
	lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
marci@1081
   557
	break;
marci@1081
   558
      case FIXED:
marci@1081
   559
	lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
marci@1081
   560
	break;
marci@1081
   561
      }
marci@1081
   562
    } 
marci@1081
   563
  protected:
marci@1031
   564
    /// \e
marci@1081
   565
    virtual double _getObjCoef(int i) { 
marci@1081
   566
      return lpx_get_obj_coef(lp, i);
marci@1031
   567
    }
marci@1031
   568
    /// \e
marci@1081
   569
    virtual void _setObjCoef(int i, double obj_coef) { 
marci@1081
   570
      lpx_set_obj_coef(lp, i, obj_coef);
marci@1031
   571
    }
marci@1081
   572
  public:
marci@1031
   573
    /// \e
marci@1031
   574
    void solveSimplex() { lpx_simplex(lp); }
marci@1031
   575
    /// \e
marci@1031
   576
    void solvePrimalSimplex() { lpx_simplex(lp); }
marci@1031
   577
    /// \e
marci@1031
   578
    void solveDualSimplex() { lpx_simplex(lp); }
marci@1031
   579
    /// \e
marci@1081
   580
  protected:
marci@1081
   581
    virtual double _getPrimal(int i) {
marci@1081
   582
      return lpx_get_col_prim(lp, i);
marci@1031
   583
    }
marci@1081
   584
  public:
marci@1031
   585
    /// \e
marci@1031
   586
    double getObjVal() { return lpx_get_obj_val(lp); }
marci@1031
   587
    /// \e
marci@1031
   588
    int rowNum() const { return lpx_get_num_rows(lp); }
marci@1031
   589
    /// \e
marci@1031
   590
    int colNum() const { return lpx_get_num_cols(lp); }
marci@1031
   591
    /// \e
marci@1031
   592
    int warmUp() { return lpx_warm_up(lp); }
marci@1031
   593
    /// \e
marci@1031
   594
    void printWarmUpStatus(int i) {
marci@1031
   595
      switch (i) {
marci@1031
   596
      case LPX_E_OK: cout << "LPX_E_OK" << endl; break;
marci@1031
   597
      case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break;	
marci@1031
   598
      case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break;
marci@1031
   599
      case LPX_E_SING: cout << "LPX_E_SING" << endl; break;
marci@1031
   600
      }
marci@1031
   601
    }
marci@1031
   602
    /// \e
marci@1031
   603
    int getPrimalStatus() { return lpx_get_prim_stat(lp); }
marci@1031
   604
    /// \e
marci@1031
   605
    void printPrimalStatus(int i) {
marci@1031
   606
      switch (i) {
marci@1031
   607
      case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break;
marci@1031
   608
      case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break;	
marci@1031
   609
      case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break;
marci@1031
   610
      case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break;
marci@1031
   611
      }
marci@1031
   612
    }
marci@1031
   613
    /// \e
marci@1031
   614
    int getDualStatus() { return lpx_get_dual_stat(lp); }
marci@1031
   615
    /// \e
marci@1031
   616
    void printDualStatus(int i) {
marci@1031
   617
      switch (i) {
marci@1031
   618
      case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break;
marci@1031
   619
      case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;	
marci@1031
   620
      case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
marci@1031
   621
      case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
marci@1031
   622
      }
marci@1031
   623
    }
marci@1031
   624
    /// Returns the status of the slack variable assigned to row \c row_it.
marci@1031
   625
    int getRowStat(const RowIt& row_it) { 
marci@1031
   626
      return lpx_get_row_stat(lp, row_iter_map[row_it]); 
marci@1031
   627
    }
marci@1031
   628
    /// \e
marci@1031
   629
    void printRowStatus(int i) {
marci@1031
   630
      switch (i) {
marci@1031
   631
      case LPX_BS: cout << "LPX_BS" << endl; break;
marci@1031
   632
      case LPX_NL: cout << "LPX_NL" << endl; break;	
marci@1031
   633
      case LPX_NU: cout << "LPX_NU" << endl; break;
marci@1031
   634
      case LPX_NF: cout << "LPX_NF" << endl; break;
marci@1031
   635
      case LPX_NS: cout << "LPX_NS" << endl; break;
marci@1031
   636
      }
marci@1031
   637
    }
marci@1031
   638
    /// Returns the status of the variable assigned to column \c col_it.
marci@1031
   639
    int getColStat(const ColIt& col_it) { 
marci@1031
   640
      return lpx_get_col_stat(lp, col_iter_map[col_it]); 
marci@1031
   641
    }
marci@1031
   642
    /// \e
marci@1031
   643
    void printColStatus(int i) {
marci@1031
   644
      switch (i) {
marci@1031
   645
      case LPX_BS: cout << "LPX_BS" << endl; break;
marci@1031
   646
      case LPX_NL: cout << "LPX_NL" << endl; break;	
marci@1031
   647
      case LPX_NU: cout << "LPX_NU" << endl; break;
marci@1031
   648
      case LPX_NF: cout << "LPX_NF" << endl; break;
marci@1031
   649
      case LPX_NS: cout << "LPX_NS" << endl; break;
marci@1031
   650
      }
marci@1031
   651
    }
marci@1031
   652
  };
marci@1031
   653
  
marci@1031
   654
  /// @}
marci@1031
   655
marci@1031
   656
} //namespace lemon
marci@1031
   657
marci@1031
   658
#endif //LEMON_LP_SOLVER_WRAPPER_H