New functions in lp_glpk.cc. Sample file: lp_sample.cc.
     2 #ifndef LEMON_LP_SOLVER_BASE_H
 
     3 #define LEMON_LP_SOLVER_BASE_H
 
    23 #include <lemon/invalid.h>
 
    24 #include <expression.h>
 
    26 //#include <lemon/max_flow.h>
 
    27 //#include <augmenting_flow.h>
 
    28 //#include <iter_map.h>
 
    39   /// \brief A partitioned vector with iterable classes.
 
    41   /// This class implements a container in which the data is stored in an 
 
    42   /// stl vector, the range is partitioned into sets and each set is 
 
    43   /// doubly linked in a list. 
 
    44   /// That is, each class is iterable by lemon iterators, and any member of 
 
    45   /// the vector can bo moved to an other class.
 
    47   class IterablePartition {
 
    51       int prev; //invalid az -1
 
    54     std::vector<Node> nodes;
 
    59     std::vector<Tip> tips;
 
    61     /// The classes are indexed by integers from \c 0 to \c classNum()-1.
 
    62     int classNum() const { return tips.size(); }
 
    63     /// This lemon style iterator iterates through a class. 
 
    65     /// Constructor. The number of classes is to be given which is fixed 
 
    66     /// over the life of the container. 
 
    67     /// The partition classes are indexed from 0 to class_num-1. 
 
    68     IterablePartition(int class_num) { 
 
    69       for (int i=0; i<class_num; ++i) {
 
    76     void befuz(Class it, int class_id) {
 
    77       if (tips[class_id].first==-1) {
 
    78 	if (tips[class_id].last==-1) {
 
    79 	  nodes[it.i].prev=nodes[it.i].next=-1;
 
    80 	  tips[class_id].first=tips[class_id].last=it.i;
 
    83 	nodes[it.i].prev=tips[class_id].last;
 
    85 	nodes[tips[class_id].last].next=it.i;
 
    86 	tips[class_id].last=it.i;
 
    89     void kifuz(Class it, int class_id) {
 
    90       if (tips[class_id].first==it.i) {
 
    91 	if (tips[class_id].last==it.i) {
 
    92 	  tips[class_id].first=tips[class_id].last=-1;
 
    94 	  tips[class_id].first=nodes[it.i].next;
 
    95 	  nodes[nodes[it.i].next].prev=-1;
 
    98 	if (tips[class_id].last==it.i) {
 
    99 	  tips[class_id].last=nodes[it.i].prev;
 
   100 	  nodes[nodes[it.i].prev].next=-1;
 
   102 	  nodes[nodes[it.i].next].prev=nodes[it.i].prev;
 
   103 	  nodes[nodes[it.i].prev].next=nodes[it.i].next;
 
   108     /// A new element with data \c t is pushed into the vector and into class 
 
   110     Class push_back(const T& t, int class_id) { 
 
   114       int i=nodes.size()-1;
 
   118     /// A member is moved to an other class.
 
   119     void set(Class it, int old_class_id, int new_class_id) {
 
   120       kifuz(it.i, old_class_id);
 
   121       befuz(it.i, new_class_id);
 
   123     /// Returns the data pointed by \c it.
 
   124     T& operator[](Class it) { return nodes[it.i].data; }
 
   125     /// Returns the data pointed by \c it.
 
   126     const T& operator[](Class it) const { return nodes[it.i].data; }
 
   129       friend class IterablePartition;
 
   133       /// Default constructor.
 
   135       /// This constructor constructs an iterator which points
 
   136       /// to the member of th container indexed by the integer _i.
 
   137       Class(const int& _i) : i(_i) { }
 
   138       /// Invalid constructor.
 
   139       Class(const Invalid&) : i(-1) { }
 
   140       friend bool operator<(const Class& x, const Class& y);
 
   141       friend std::ostream& operator<<(std::ostream& os, 
 
   143       bool operator==(const Class& node) const {return i == node.i;}
 
   144       bool operator!=(const Class& node) const {return i != node.i;}
 
   146     friend bool operator<(const Class& x, const Class& y) {
 
   149     friend std::ostream& operator<<(std::ostream& os, 
 
   154     /// First member of class \c class_id.
 
   155     Class& first(Class& it, int class_id) const {
 
   156       it.i=tips[class_id].first;
 
   160     Class& next(Class& it) const {
 
   161       it.i=nodes[it.i].next;
 
   164     /// True iff the iterator is valid.
 
   165     bool valid(const Class& it) const { return it.i!=-1; }
 
   167     class ClassIt : public Class {
 
   168       const IterablePartition* iterable_partition;
 
   171       ClassIt(Invalid i) : Class(i) { }
 
   172       ClassIt(const IterablePartition& _iterable_partition, 
 
   173 	      const int& i) : iterable_partition(&_iterable_partition) {
 
   174         _iterable_partition.first(*this, i);
 
   176       ClassIt(const IterablePartition& _iterable_partition, 
 
   177 	      const Class& _class) : 
 
   178 	Class(_class), iterable_partition(&_iterable_partition) { }
 
   179       ClassIt& operator++() {
 
   180         iterable_partition->next(*this);
 
   189     \todo kellenene uj iterable structure bele, mert ez nem az igazi
 
   190     \todo A[x,y]-t cserel. Jobboldal, baloldal csere.
 
   191     \todo LEKERDEZESEK!!!
 
   192     \todo DOKSI!!!! Doxygen group!!!
 
   193     The aim of this class is to give a general surface to different 
 
   194     solvers, i.e. it makes possible to write algorithms using LP's, 
 
   195     in which the solver can be changed to an other one easily.
 
   198   template <typename _Value>
 
   201     /*! @name Uncategorized functions and types (public members)
 
   209     typedef IterablePartition<int> Rows;
 
   211     typedef IterablePartition<int> Cols;
 
   213     typedef _Value Value;
 
   215     typedef Rows::Class Row;
 
   217     typedef Cols::Class Col;
 
   220     IterablePartition<int> row_iter_map;
 
   222     IterablePartition<int> col_iter_map;
 
   224     std::vector<Row> int_row_map;
 
   226     std::vector<Col> int_col_map;
 
   228     const int VALID_CLASS;
 
   230     const int INVALID_CLASS;
 
   232     static const Value INF;
 
   235     LpSolverBase() : row_iter_map(2), 
 
   237 		     VALID_CLASS(0), INVALID_CLASS(1) { }
 
   239     virtual ~LpSolverBase() { }
 
   242     /*! @name Medium level interface (public members)
 
   243       These functions appear in the low level and also in the high level 
 
   244       interfaces thus these each of these functions have to be implemented 
 
   245       only once in the different interfaces.
 
   246       This means that these functions have to be reimplemented for all of the 
 
   247       different lp solvers. These are basic functions, and have the same 
 
   248       parameter lists in the low and high level interfaces. 
 
   253     //UNCATEGORIZED FUNCTIONS
 
   256     virtual void setMinimize() = 0;
 
   258     virtual void setMaximize() = 0;
 
   263     virtual void solveSimplex() = 0;
 
   265     virtual void solvePrimalSimplex() = 0;
 
   267     virtual void solveDualSimplex() = 0;
 
   269     //SOLUTION RETRIEVING
 
   272     virtual Value getObjVal() = 0;
 
   277     virtual int rowNum() const = 0;
 
   279     virtual int colNum() const = 0;
 
   281     virtual int warmUp() = 0;
 
   283     virtual void printWarmUpStatus(int i) = 0;
 
   285     virtual int getPrimalStatus() = 0;
 
   287     virtual void printPrimalStatus(int i) = 0;
 
   289     virtual int getDualStatus() = 0;
 
   291     virtual void printDualStatus(int i) = 0;
 
   292     /// Returns the status of the slack variable assigned to row \c row.
 
   293     virtual int getRowStat(const Row& row) = 0;
 
   295     virtual void printRowStatus(int i) = 0;
 
   296     /// Returns the status of the variable assigned to column \c col.
 
   297     virtual int getColStat(const Col& col) = 0;
 
   299     virtual void printColStatus(int i) = 0;
 
   303     /*! @name Low level interface (protected members)
 
   304       Problem manipulating functions in the low level interface
 
   309     //MATRIX MANIPULATING FUNCTIONS
 
   312     virtual int _addCol() = 0;
 
   314     virtual int _addRow() = 0;
 
   316     virtual void _eraseCol(int i) = 0;
 
   318     virtual void _eraseRow(int i) = 0;
 
   320     virtual void _setRowCoeffs(int i, 
 
   321 			       const std::vector<std::pair<int, Value> >& coeffs) = 0;
 
   323     /// This routine modifies \c coeffs only by the \c push_back method.
 
   324     virtual void _getRowCoeffs(int i, 
 
   325 			       std::vector<std::pair<int, Value> >& coeffs) = 0;
 
   327     virtual void _setColCoeffs(int i, 
 
   328 			       const std::vector<std::pair<int, Value> >& coeffs) = 0;
 
   330     /// This routine modifies \c coeffs only by the \c push_back method.
 
   331     virtual void _getColCoeffs(int i, 
 
   332 			       std::vector<std::pair<int, Value> >& coeffs) = 0;
 
   334     virtual void _setCoeff(int col, int row, Value value) = 0;
 
   336     virtual Value _getCoeff(int col, int row) = 0;
 
   339     //    enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
 
   342     /// The lower bound of a variable (column) have to be given by an 
 
   343     /// extended number of type Value, i.e. a finite number of type 
 
   345     virtual void _setColLowerBound(int i, Value value) = 0;
 
   347     /// The lower bound of a variable (column) is an 
 
   348     /// extended number of type Value, i.e. a finite number of type 
 
   350     virtual Value _getColLowerBound(int i) = 0;
 
   352     /// The upper bound of a variable (column) have to be given by an 
 
   353     /// extended number of type Value, i.e. a finite number of type 
 
   355     virtual void _setColUpperBound(int i, Value value) = 0;
 
   357     /// The upper bound of a variable (column) is an 
 
   358     /// extended number of type Value, i.e. a finite number of type 
 
   360     virtual Value _getColUpperBound(int i) = 0;
 
   362     /// The lower bound of a linear expression (row) have to be given by an 
 
   363     /// extended number of type Value, i.e. a finite number of type 
 
   365     virtual void _setRowLowerBound(int i, Value value) = 0;
 
   367     /// The lower bound of a linear expression (row) is an 
 
   368     /// extended number of type Value, i.e. a finite number of type 
 
   370     virtual Value _getRowLowerBound(int i) = 0;
 
   372     /// The upper bound of a linear expression (row) have to be given by an 
 
   373     /// extended number of type Value, i.e. a finite number of type 
 
   375     virtual void _setRowUpperBound(int i, Value value) = 0;
 
   377     /// The upper bound of a linear expression (row) is an 
 
   378     /// extended number of type Value, i.e. a finite number of type 
 
   380     virtual Value _getRowUpperBound(int i) = 0;
 
   382     virtual void _setObjCoeff(int i, Value obj_coef) = 0;
 
   384     virtual Value _getObjCoeff(int i) = 0;
 
   386     //SOLUTION RETRIEVING
 
   389     virtual Value _getPrimal(int i) = 0;
 
   392     /*! @name High level interface (public members)
 
   393       Problem manipulating functions in the high level interface
 
   398     //MATRIX MANIPULATING FUNCTIONS
 
   404       col_iter_map.first(col, INVALID_CLASS);
 
   405       if (col_iter_map.valid(col)) { //van hasznalhato hely
 
   406 	col_iter_map.set(col, INVALID_CLASS, VALID_CLASS);
 
   408       } else { //a cucc vegere kell inzertalni mert nincs szabad hely
 
   409 	col=col_iter_map.push_back(i, VALID_CLASS);
 
   411       int_col_map.push_back(col);
 
   418       row_iter_map.first(row, INVALID_CLASS);
 
   419       if (row_iter_map.valid(row)) { //van hasznalhato hely
 
   420 	row_iter_map.set(row, INVALID_CLASS, VALID_CLASS);
 
   422       } else { //a cucc vegere kell inzertalni mert nincs szabad hely
 
   423 	row=row_iter_map.push_back(i, VALID_CLASS);
 
   425       int_row_map.push_back(row);
 
   429     void eraseCol(const Col& col) {
 
   430       col_iter_map.set(col, VALID_CLASS, INVALID_CLASS);
 
   432       cols[1]=col_iter_map[col];
 
   434       col_iter_map[col]=0; //glpk specifikus, de kell ez??
 
   436       for (col_iter_map.first(it, VALID_CLASS); 
 
   437 	   col_iter_map.valid(it); col_iter_map.next(it)) {
 
   438 	if (col_iter_map[it]>cols[1]) --col_iter_map[it];
 
   440       int_col_map.erase(int_col_map.begin()+cols[1]);
 
   443     void eraseRow(const Row& row) {
 
   444       row_iter_map.set(row, VALID_CLASS, INVALID_CLASS);
 
   446       rows[1]=row_iter_map[row];
 
   448       row_iter_map[row]=0; //glpk specifikus, de kell ez??
 
   450       for (row_iter_map.first(it, VALID_CLASS); 
 
   451 	   row_iter_map.valid(it); row_iter_map.next(it)) {
 
   452 	if (row_iter_map[it]>rows[1]) --row_iter_map[it];
 
   454       int_row_map.erase(int_row_map.begin()+rows[1]);
 
   457     void setCoeff(Col col, Row row, Value value) {
 
   458       _setCoeff(col_iter_map[col], row_iter_map[row], value);
 
   461     Value getCoeff(Col col, Row row) {
 
   462       return _getCoeff(col_iter_map[col], row_iter_map[row], value);
 
   465     void setColLowerBound(Col col, Value lo) {
 
   466       _setColLowerBound(col_iter_map[col], lo);
 
   469     Value getColLowerBound(Col col) {
 
   470       return _getColLowerBound(col_iter_map[col]);
 
   473     void setColUpperBound(Col col, Value up) {
 
   474       _setColUpperBound(col_iter_map[col], up);
 
   477     Value getColUpperBound(Col col) {      
 
   478       return _getColUpperBound(col_iter_map[col]);
 
   481     void setRowLowerBound(Row row, Value lo) {
 
   482       _setRowLowerBound(row_iter_map[row], lo);
 
   485     Value getRowLowerBound(Row row) {
 
   486       return _getRowLowerBound(row_iter_map[row]);
 
   489     void setRowUpperBound(Row row, Value up) {
 
   490       _setRowUpperBound(row_iter_map[row], up);
 
   493     Value getRowUpperBound(Row row) {      
 
   494       return _getRowUpperBound(row_iter_map[row]);
 
   497     void setObjCoeff(const Col& col, Value obj_coef) {
 
   498       _setObjCoeff(col_iter_map[col], obj_coef);
 
   501     Value getObjCoeff(const Col& col) {
 
   502       return _getObjCoeff(col_iter_map[col]);
 
   505     //SOLUTION RETRIEVING FUNCTIONS
 
   508     Value getPrimal(const Col& col) {
 
   509       return _getPrimal(col_iter_map[col]);
 
   514     /*! @name User friend interface
 
   515       Problem manipulating functions in the user friend interface
 
   522     typedef Expr<Col, Value> Expression;
 
   524     typedef Expr<Row, Value> DualExpression;
 
   526     typedef Constr<Col, Value> Constraint;
 
   528     //MATRIX MANIPULATING FUNCTIONS
 
   531     void setRowCoeffs(Row row, const Expression& expr) {
 
   532       std::vector<std::pair<int, Value> > row_coeffs;
 
   533       for(typename Expression::Data::const_iterator i=expr.data.begin(); 
 
   534 	  i!=expr.data.end(); ++i) {
 
   535 	row_coeffs.push_back(std::make_pair
 
   536 			     (col_iter_map[(*i).first], (*i).second));
 
   538       _setRowCoeffs(row_iter_map[row], row_coeffs);
 
   541     void setRow(Row row, const Constraint& constr) {
 
   542       setRowCoeffs(row, constr.expr);
 
   543       setRowLowerBound(row, constr.lo);
 
   544       setRowUpperBound(row, constr.up);
 
   547     Row addRow(const Constraint& constr) {
 
   549       setRowCoeffs(row, constr.expr);
 
   550       setRowLowerBound(row, constr.lo);
 
   551       setRowUpperBound(row, constr.up);
 
   555     /// This routine modifies \c expr by only adding to it.
 
   556     void getRowCoeffs(Row row, Expression& expr) {
 
   557       std::vector<std::pair<int, Value> > row_coeffs;
 
   558       _getRowCoeffs(row_iter_map[row], row_coeffs);
 
   559       for(typename std::vector<std::pair<int, Value> >::const_iterator 
 
   560  	    i=row_coeffs.begin(); i!=row_coeffs.end(); ++i) {
 
   561  	expr+= (*i).second*int_col_map[(*i).first];
 
   565     void setColCoeffs(Col col, const DualExpression& expr) {
 
   566       std::vector<std::pair<int, Value> > col_coeffs;
 
   567       for(typename DualExpression::Data::const_iterator i=expr.data.begin(); 
 
   568 	  i!=expr.data.end(); ++i) {
 
   569 	col_coeffs.push_back(std::make_pair
 
   570 			     (row_iter_map[(*i).first], (*i).second));
 
   572       _setColCoeffs(col_iter_map[col], col_coeffs);
 
   575     /// This routine modifies \c expr by only adding to it.
 
   576     void getColCoeffs(Col col, DualExpression& expr) {
 
   577       std::vector<std::pair<int, Value> > col_coeffs;
 
   578       _getColCoeffs(col_iter_map[col], col_coeffs);
 
   579       for(typename std::vector<std::pair<int, Value> >::const_iterator 
 
   580  	    i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) {
 
   581  	expr+= (*i).second*int_row_map[(*i).first];
 
   585     void setObjCoeffs(const Expression& expr) {
 
   586       // writing zero everywhere
 
   587       for(Cols::ClassIt it(col_iter_map, VALID_CLASS); it!=INVALID; ++it)
 
   588 	setObjCoeff(it, 0.0);
 
   589       // writing the data needed
 
   590       for(typename Expression::Data::const_iterator i=expr.data.begin(); 
 
   591 	  i!=expr.data.end(); ++i) {
 
   592 	setObjCoeff((*i).first, (*i).second);
 
   596     /// This routine modifies \c expr by only adding to it.
 
   597     void getObjCoeffs(Expression& expr) {
 
   598       for(Cols::ClassIt it(col_iter_map, VALID_CLASS); it!=INVALID; ++it)
 
   599 	expr+=getObjCoeff(it)*it;
 
   604     /*! @name MIP functions and types (public members)
 
   609     virtual void solveBandB() = 0;
 
   611     virtual void setLP() = 0;
 
   613     virtual void setMIP() = 0;
 
   616     virtual void _setColCont(int i) = 0;
 
   618     virtual void _setColInt(int i) = 0;
 
   620     virtual Value _getMIPPrimal(int i) = 0;
 
   623     void setColCont(Col col) {
 
   624       _setColCont(col_iter_map[col]);
 
   627     void setColInt(Col col) {
 
   628       _setColInt(col_iter_map[col]);
 
   631     Value getMIPPrimal(Col col) {
 
   632       return _getMIPPrimal(col_iter_map[col]);
 
   639 #endif //LEMON_LP_SOLVER_BASE_H