src/work/athos/lp_old/lp_solver_base.h
changeset 1365 c280de819a73
parent 1241 dadc9987c537
equal deleted inserted replaced
0:74645cedb8bf -1:000000000000
     1 // -*- c++ -*-
       
     2 #ifndef LEMON_LP_SOLVER_BASE_H
       
     3 #define LEMON_LP_SOLVER_BASE_H
       
     4 
       
     5 ///\ingroup misc
       
     6 ///\file
       
     7 
       
     8 // #include <stdio.h>
       
     9 #include <stdlib.h>
       
    10 #include <iostream>
       
    11 #include <map>
       
    12 #include <limits>
       
    13 // #include <stdio>
       
    14 //#include <stdlib>
       
    15 
       
    16 #include <iostream>
       
    17 #include <vector>
       
    18 #include <string>
       
    19 #include <list>
       
    20 #include <memory>
       
    21 #include <utility>
       
    22 
       
    23 #include <lemon/invalid.h>
       
    24 #include <expression.h>
       
    25 //#include <stp.h>
       
    26 //#include <lemon/max_flow.h>
       
    27 //#include <augmenting_flow.h>
       
    28 //#include <iter_map.h>
       
    29 
       
    30 using std::cout;
       
    31 using std::cin;
       
    32 using std::endl;
       
    33 
       
    34 namespace lemon {
       
    35   
       
    36   /// \addtogroup misc
       
    37   /// @{
       
    38 
       
    39   /// \brief A partitioned vector with iterable classes.
       
    40   ///
       
    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.
       
    46   template <typename T>
       
    47   class IterablePartition {
       
    48   protected:
       
    49     struct Node {
       
    50       T data;
       
    51       int prev; //invalid az -1
       
    52       int next; 
       
    53     };
       
    54     std::vector<Node> nodes;
       
    55     struct Tip {
       
    56       int first;
       
    57       int last;
       
    58     };
       
    59     std::vector<Tip> tips;
       
    60   public:
       
    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. 
       
    64     class 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) {
       
    70 	Tip t;
       
    71 	t.first=t.last=-1;
       
    72 	tips.push_back(t);
       
    73       }
       
    74     }
       
    75   protected:
       
    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;
       
    81 	}
       
    82       } else {
       
    83 	nodes[it.i].prev=tips[class_id].last;
       
    84 	nodes[it.i].next=-1;
       
    85 	nodes[tips[class_id].last].next=it.i;
       
    86 	tips[class_id].last=it.i;
       
    87       }
       
    88     }
       
    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;
       
    93 	} else {
       
    94 	  tips[class_id].first=nodes[it.i].next;
       
    95 	  nodes[nodes[it.i].next].prev=-1;
       
    96 	}
       
    97       } else {
       
    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;
       
   101 	} else {
       
   102 	  nodes[nodes[it.i].next].prev=nodes[it.i].prev;
       
   103 	  nodes[nodes[it.i].prev].next=nodes[it.i].next;
       
   104 	}
       
   105       }
       
   106     }
       
   107   public:
       
   108     /// A new element with data \c t is pushed into the vector and into class 
       
   109     /// \c class_id.
       
   110     Class push_back(const T& t, int class_id) { 
       
   111       Node n;
       
   112       n.data=t;
       
   113       nodes.push_back(n);
       
   114       int i=nodes.size()-1;
       
   115       befuz(i, class_id);
       
   116       return i;
       
   117     }
       
   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);
       
   122     }
       
   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; }
       
   127     ///.
       
   128     class Class {
       
   129       friend class IterablePartition;
       
   130     protected:
       
   131       int i;
       
   132     public:
       
   133       /// Default constructor.
       
   134       Class() { }
       
   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, 
       
   142 				      const Class& it);
       
   143       bool operator==(const Class& node) const {return i == node.i;}
       
   144       bool operator!=(const Class& node) const {return i != node.i;}
       
   145     };
       
   146     friend bool operator<(const Class& x, const Class& y) {
       
   147       return (x.i < y.i);
       
   148     }
       
   149     friend std::ostream& operator<<(std::ostream& os, 
       
   150 				    const Class& it) {
       
   151       os << it.i;
       
   152       return os;
       
   153     }
       
   154     /// First member of class \c class_id.
       
   155     Class& first(Class& it, int class_id) const {
       
   156       it.i=tips[class_id].first;
       
   157       return it;
       
   158     }
       
   159     /// Next member.
       
   160     Class& next(Class& it) const {
       
   161       it.i=nodes[it.i].next;
       
   162       return it;
       
   163     }
       
   164     /// True iff the iterator is valid.
       
   165     bool valid(const Class& it) const { return it.i!=-1; }
       
   166 
       
   167     class ClassIt : public Class {
       
   168       const IterablePartition* iterable_partition;
       
   169     public:
       
   170       ClassIt() { }
       
   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);
       
   175       }
       
   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);
       
   181         return *this;
       
   182       }
       
   183     };
       
   184 
       
   185   };
       
   186 
       
   187 
       
   188   /*! \e
       
   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.
       
   196     \nosubgrouping
       
   197   */
       
   198   template <typename _Value>
       
   199   class LpSolverBase {
       
   200     
       
   201     /*! @name Uncategorized functions and types (public members)
       
   202     */
       
   203     //@{
       
   204   public:
       
   205 
       
   206     //UNCATEGORIZED
       
   207 
       
   208     /// \e
       
   209     typedef IterablePartition<int> Rows;
       
   210     /// \e
       
   211     typedef IterablePartition<int> Cols;
       
   212     /// \e
       
   213     typedef _Value Value;
       
   214     /// \e
       
   215     typedef Rows::Class Row;
       
   216     /// \e
       
   217     typedef Cols::Class Col;
       
   218   public:
       
   219     /// \e
       
   220     IterablePartition<int> row_iter_map;
       
   221     /// \e
       
   222     IterablePartition<int> col_iter_map;
       
   223     /// \e
       
   224     std::vector<Row> int_row_map;
       
   225     /// \e
       
   226     std::vector<Col> int_col_map;
       
   227     /// \e
       
   228     const int VALID_CLASS;
       
   229     /// \e
       
   230     const int INVALID_CLASS;
       
   231     /// \e 
       
   232     static const Value INF;
       
   233   public:
       
   234     /// \e
       
   235     LpSolverBase() : row_iter_map(2), 
       
   236 		     col_iter_map(2), 
       
   237 		     VALID_CLASS(0), INVALID_CLASS(1) { }
       
   238     /// \e
       
   239     virtual ~LpSolverBase() { }
       
   240     //@}
       
   241 
       
   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. 
       
   249     */
       
   250     //@{
       
   251   public:
       
   252 
       
   253     //UNCATEGORIZED FUNCTIONS
       
   254 
       
   255     /// \e
       
   256     virtual void setMinimize() = 0;
       
   257     /// \e
       
   258     virtual void setMaximize() = 0;
       
   259 
       
   260     //SOLVER FUNCTIONS
       
   261 
       
   262     /// \e
       
   263     virtual void solveSimplex() = 0;
       
   264     /// \e
       
   265     virtual void solvePrimalSimplex() = 0;
       
   266     /// \e
       
   267     virtual void solveDualSimplex() = 0;
       
   268 
       
   269     //SOLUTION RETRIEVING
       
   270 
       
   271     /// \e
       
   272     virtual Value getObjVal() = 0;
       
   273 
       
   274     //OTHER FUNCTIONS
       
   275 
       
   276     /// \e
       
   277     virtual int rowNum() const = 0;
       
   278     /// \e
       
   279     virtual int colNum() const = 0;
       
   280     /// \e
       
   281     virtual int warmUp() = 0;
       
   282     /// \e
       
   283     virtual void printWarmUpStatus(int i) = 0;
       
   284     /// \e
       
   285     virtual int getPrimalStatus() = 0;
       
   286     /// \e
       
   287     virtual void printPrimalStatus(int i) = 0;
       
   288     /// \e
       
   289     virtual int getDualStatus() = 0;
       
   290     /// \e
       
   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;
       
   294     /// \e
       
   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;
       
   298     /// \e
       
   299     virtual void printColStatus(int i) = 0;
       
   300 
       
   301     //@}
       
   302 
       
   303     /*! @name Low level interface (protected members)
       
   304       Problem manipulating functions in the low level interface
       
   305     */
       
   306     //@{
       
   307   protected:
       
   308 
       
   309     //MATRIX MANIPULATING FUNCTIONS
       
   310 
       
   311     /// \e
       
   312     virtual int _addCol() = 0;
       
   313     /// \e
       
   314     virtual int _addRow() = 0;
       
   315     /// \e
       
   316     virtual void _eraseCol(int i) = 0;
       
   317     /// \e
       
   318     virtual void _eraseRow(int i) = 0;
       
   319     /// \e
       
   320     virtual void _setRowCoeffs(int i, 
       
   321 			       const std::vector<std::pair<int, Value> >& coeffs) = 0;
       
   322     /// \e
       
   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;
       
   326     /// \e
       
   327     virtual void _setColCoeffs(int i, 
       
   328 			       const std::vector<std::pair<int, Value> >& coeffs) = 0;
       
   329     /// \e
       
   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;
       
   333     /// \e
       
   334     virtual void _setCoeff(int col, int row, Value value) = 0;
       
   335     /// \e
       
   336     virtual Value _getCoeff(int col, int row) = 0;
       
   337     //  public:
       
   338     //    /// \e
       
   339     //    enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
       
   340   protected:
       
   341     /// \e
       
   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 
       
   344     /// Value or -INF.
       
   345     virtual void _setColLowerBound(int i, Value value) = 0;
       
   346     /// \e
       
   347     /// The lower bound of a variable (column) is an 
       
   348     /// extended number of type Value, i.e. a finite number of type 
       
   349     /// Value or -INF.
       
   350     virtual Value _getColLowerBound(int i) = 0;
       
   351     /// \e
       
   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 
       
   354     /// Value or INF.
       
   355     virtual void _setColUpperBound(int i, Value value) = 0;
       
   356     /// \e
       
   357     /// The upper bound of a variable (column) is an 
       
   358     /// extended number of type Value, i.e. a finite number of type 
       
   359     /// Value or INF.
       
   360     virtual Value _getColUpperBound(int i) = 0;
       
   361     /// \e
       
   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 
       
   364     /// Value or -INF.
       
   365     virtual void _setRowLowerBound(int i, Value value) = 0;
       
   366     /// \e
       
   367     /// The lower bound of a linear expression (row) is an 
       
   368     /// extended number of type Value, i.e. a finite number of type 
       
   369     /// Value or -INF.
       
   370     virtual Value _getRowLowerBound(int i) = 0;
       
   371     /// \e
       
   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 
       
   374     /// Value or INF.
       
   375     virtual void _setRowUpperBound(int i, Value value) = 0;
       
   376     /// \e
       
   377     /// The upper bound of a linear expression (row) is an 
       
   378     /// extended number of type Value, i.e. a finite number of type 
       
   379     /// Value or INF.
       
   380     virtual Value _getRowUpperBound(int i) = 0;
       
   381     /// \e
       
   382     virtual void _setObjCoeff(int i, Value obj_coef) = 0;
       
   383     /// \e
       
   384     virtual Value _getObjCoeff(int i) = 0;
       
   385     
       
   386     //SOLUTION RETRIEVING
       
   387 
       
   388     /// \e
       
   389     virtual Value _getPrimal(int i) = 0;
       
   390     //@}
       
   391     
       
   392     /*! @name High level interface (public members)
       
   393       Problem manipulating functions in the high level interface
       
   394     */
       
   395     //@{
       
   396   public:
       
   397 
       
   398     //MATRIX MANIPULATING FUNCTIONS
       
   399 
       
   400     /// \e
       
   401     Col addCol() {
       
   402       int i=_addCol();  
       
   403       Col col;
       
   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);
       
   407 	col_iter_map[col]=i;
       
   408       } else { //a cucc vegere kell inzertalni mert nincs szabad hely
       
   409 	col=col_iter_map.push_back(i, VALID_CLASS);
       
   410       }
       
   411       int_col_map.push_back(col);
       
   412       return col;
       
   413     }
       
   414     /// \e
       
   415     Row addRow() {
       
   416       int i=_addRow();
       
   417       Row row;
       
   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);
       
   421 	row_iter_map[row]=i;
       
   422       } else { //a cucc vegere kell inzertalni mert nincs szabad hely
       
   423 	row=row_iter_map.push_back(i, VALID_CLASS);
       
   424       }
       
   425       int_row_map.push_back(row);
       
   426       return row;
       
   427     }
       
   428     /// \e
       
   429     void eraseCol(const Col& col) {
       
   430       col_iter_map.set(col, VALID_CLASS, INVALID_CLASS);
       
   431       int cols[2];
       
   432       cols[1]=col_iter_map[col];
       
   433       _eraseCol(cols[1]);
       
   434       col_iter_map[col]=0; //glpk specifikus, de kell ez??
       
   435       Col it;
       
   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];
       
   439       }
       
   440       int_col_map.erase(int_col_map.begin()+cols[1]);
       
   441     }
       
   442     /// \e
       
   443     void eraseRow(const Row& row) {
       
   444       row_iter_map.set(row, VALID_CLASS, INVALID_CLASS);
       
   445       int rows[2];
       
   446       rows[1]=row_iter_map[row];
       
   447       _eraseRow(rows[1]);
       
   448       row_iter_map[row]=0; //glpk specifikus, de kell ez??
       
   449       Row it;
       
   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];
       
   453       }
       
   454       int_row_map.erase(int_row_map.begin()+rows[1]);
       
   455     }
       
   456     /// \e
       
   457     void setCoeff(Col col, Row row, Value value) {
       
   458       _setCoeff(col_iter_map[col], row_iter_map[row], value);
       
   459     }
       
   460     /// \e
       
   461     Value getCoeff(Col col, Row row) {
       
   462       return _getCoeff(col_iter_map[col], row_iter_map[row], value);
       
   463     }
       
   464     /// \e
       
   465     void setColLowerBound(Col col, Value lo) {
       
   466       _setColLowerBound(col_iter_map[col], lo);
       
   467     }
       
   468     /// \e
       
   469     Value getColLowerBound(Col col) {
       
   470       return _getColLowerBound(col_iter_map[col]);
       
   471     }
       
   472     /// \e
       
   473     void setColUpperBound(Col col, Value up) {
       
   474       _setColUpperBound(col_iter_map[col], up);
       
   475     }
       
   476     /// \e
       
   477     Value getColUpperBound(Col col) {      
       
   478       return _getColUpperBound(col_iter_map[col]);
       
   479     }
       
   480     /// \e
       
   481     void setRowLowerBound(Row row, Value lo) {
       
   482       _setRowLowerBound(row_iter_map[row], lo);
       
   483     }
       
   484     /// \e
       
   485     Value getRowLowerBound(Row row) {
       
   486       return _getRowLowerBound(row_iter_map[row]);
       
   487     }
       
   488     /// \e
       
   489     void setRowUpperBound(Row row, Value up) {
       
   490       _setRowUpperBound(row_iter_map[row], up);
       
   491     }
       
   492     /// \e
       
   493     Value getRowUpperBound(Row row) {      
       
   494       return _getRowUpperBound(row_iter_map[row]);
       
   495     }
       
   496     /// \e
       
   497     void setObjCoeff(const Col& col, Value obj_coef) {
       
   498       _setObjCoeff(col_iter_map[col], obj_coef);
       
   499     }
       
   500     /// \e
       
   501     Value getObjCoeff(const Col& col) {
       
   502       return _getObjCoeff(col_iter_map[col]);
       
   503     }
       
   504 
       
   505     //SOLUTION RETRIEVING FUNCTIONS
       
   506 
       
   507     /// \e
       
   508     Value getPrimal(const Col& col) {
       
   509       return _getPrimal(col_iter_map[col]);
       
   510     }    
       
   511 
       
   512     //@}
       
   513 
       
   514     /*! @name User friend interface
       
   515       Problem manipulating functions in the user friend interface
       
   516     */
       
   517     //@{
       
   518 
       
   519     //EXPRESSION TYPES
       
   520 
       
   521     /// \e
       
   522     typedef Expr<Col, Value> Expression;
       
   523     /// \e
       
   524     typedef Expr<Row, Value> DualExpression;
       
   525     /// \e
       
   526     typedef Constr<Col, Value> Constraint;
       
   527 
       
   528     //MATRIX MANIPULATING FUNCTIONS
       
   529 
       
   530     /// \e
       
   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));
       
   537       }
       
   538       _setRowCoeffs(row_iter_map[row], row_coeffs);
       
   539     }
       
   540     /// \e 
       
   541     void setRow(Row row, const Constraint& constr) {
       
   542       setRowCoeffs(row, constr.expr);
       
   543       setRowLowerBound(row, constr.lo);
       
   544       setRowUpperBound(row, constr.up);
       
   545     }
       
   546     /// \e 
       
   547     Row addRow(const Constraint& constr) {
       
   548       Row row=addRow();
       
   549       setRowCoeffs(row, constr.expr);
       
   550       setRowLowerBound(row, constr.lo);
       
   551       setRowUpperBound(row, constr.up);
       
   552       return row;
       
   553     }
       
   554     /// \e
       
   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];
       
   562       }
       
   563     }
       
   564     /// \e
       
   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));
       
   571       }
       
   572       _setColCoeffs(col_iter_map[col], col_coeffs);
       
   573     }
       
   574     /// \e
       
   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];
       
   582       }
       
   583     }
       
   584     /// \e
       
   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);
       
   593       }
       
   594     }
       
   595     /// \e
       
   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;
       
   600     }
       
   601     //@}
       
   602 
       
   603 
       
   604     /*! @name MIP functions and types (public members)
       
   605     */
       
   606     //@{
       
   607   public:
       
   608     /// \e
       
   609     virtual void solveBandB() = 0;
       
   610     /// \e
       
   611     virtual void setLP() = 0;
       
   612     /// \e
       
   613     virtual void setMIP() = 0;
       
   614   protected:
       
   615    /// \e
       
   616     virtual void _setColCont(int i) = 0;
       
   617     /// \e
       
   618     virtual void _setColInt(int i) = 0;
       
   619     /// \e
       
   620     virtual Value _getMIPPrimal(int i) = 0;
       
   621   public:
       
   622     /// \e
       
   623     void setColCont(Col col) {
       
   624       _setColCont(col_iter_map[col]);
       
   625     }
       
   626     /// \e
       
   627     void setColInt(Col col) {
       
   628       _setColInt(col_iter_map[col]);
       
   629     }
       
   630     /// \e
       
   631     Value getMIPPrimal(Col col) {
       
   632       return _getMIPPrimal(col_iter_map[col]);
       
   633     }
       
   634     //@}
       
   635   };
       
   636 
       
   637 } //namespace lemon
       
   638 
       
   639 #endif //LEMON_LP_SOLVER_BASE_H