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