COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/athos/lp/lp_solver_base.h @ 1241:dadc9987c537

Last change on this file since 1241:dadc9987c537 was 1241:dadc9987c537, checked in by athos, 19 years ago

Modified a bit.

File size: 18.1 KB
RevLine 
[1031]1// -*- c++ -*-
[1152]2#ifndef LEMON_LP_SOLVER_BASE_H
3#define LEMON_LP_SOLVER_BASE_H
[1031]4
5///\ingroup misc
6///\file
7
8// #include <stdio.h>
9#include <stdlib.h>
[1097]10#include <iostream>
11#include <map>
[1104]12#include <limits>
[1031]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>
[1099]24#include <expression.h>
[1031]25//#include <stp.h>
26//#include <lemon/max_flow.h>
27//#include <augmenting_flow.h>
28//#include <iter_map.h>
29
30using std::cout;
31using std::cin;
32using std::endl;
33
34namespace 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.
[1152]64    class Class;
[1031]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:
[1152]76    void befuz(Class it, int class_id) {
[1031]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    }
[1152]89    void kifuz(Class it, int class_id) {
[1031]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.
[1152]110    Class push_back(const T& t, int class_id) {
[1031]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.
[1152]119    void set(Class it, int old_class_id, int new_class_id) {
[1031]120      kifuz(it.i, old_class_id);
121      befuz(it.i, new_class_id);
122    }
123    /// Returns the data pointed by \c it.
[1152]124    T& operator[](Class it) { return nodes[it.i].data; }
[1031]125    /// Returns the data pointed by \c it.
[1152]126    const T& operator[](Class it) const { return nodes[it.i].data; }
[1031]127    ///.
[1152]128    class Class {
[1031]129      friend class IterablePartition;
130    protected:
131      int i;
132    public:
133      /// Default constructor.
[1152]134      Class() { }
[1031]135      /// This constructor constructs an iterator which points
136      /// to the member of th container indexed by the integer _i.
[1152]137      Class(const int& _i) : i(_i) { }
[1031]138      /// Invalid constructor.
[1152]139      Class(const Invalid&) : i(-1) { }
140      friend bool operator<(const Class& x, const Class& y);
[1099]141      friend std::ostream& operator<<(std::ostream& os,
[1152]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;}
[1031]145    };
[1152]146    friend bool operator<(const Class& x, const Class& y) {
[1099]147      return (x.i < y.i);
148    }
149    friend std::ostream& operator<<(std::ostream& os,
[1152]150                                    const Class& it) {
[1099]151      os << it.i;
152      return os;
153    }
[1031]154    /// First member of class \c class_id.
[1152]155    Class& first(Class& it, int class_id) const {
[1031]156      it.i=tips[class_id].first;
157      return it;
158    }
159    /// Next member.
[1152]160    Class& next(Class& it) const {
[1031]161      it.i=nodes[it.i].next;
162      return it;
163    }
164    /// True iff the iterator is valid.
[1152]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
[1031]185  };
186
[1097]187
[1031]188  /*! \e
[1143]189    \todo kellenene uj iterable structure bele, mert ez nem az igazi
[1111]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.
[1112]196    \nosubgrouping
[1111]197  */
[1048]198  template <typename _Value>
[1241]199  class LpSolverBase {
[1112]200   
[1113]201    /*! @name Uncategorized functions and types (public members)
[1112]202    */
203    //@{
[1031]204  public:
[1112]205
206    //UNCATEGORIZED
207
[1031]208    /// \e
[1152]209    typedef IterablePartition<int> Rows;
210    /// \e
211    typedef IterablePartition<int> Cols;
212    /// \e
[1048]213    typedef _Value Value;
214    /// \e
[1152]215    typedef Rows::Class Row;
[1031]216    /// \e
[1152]217    typedef Cols::Class Col;
[1074]218  public:
[1031]219    /// \e
220    IterablePartition<int> row_iter_map;
221    /// \e
222    IterablePartition<int> col_iter_map;
223    /// \e
[1144]224    std::vector<Row> int_row_map;
[1143]225    /// \e
[1144]226    std::vector<Col> int_col_map;
[1143]227    /// \e
[1074]228    const int VALID_CLASS;
[1031]229    /// \e
[1074]230    const int INVALID_CLASS;
[1104]231    /// \e
[1241]232    static const Value INF;
[1031]233  public:
234    /// \e
[1241]235    LpSolverBase() : row_iter_map(2),
[1031]236                     col_iter_map(2),
[1074]237                     VALID_CLASS(0), INVALID_CLASS(1) { }
[1031]238    /// \e
[1241]239    virtual ~LpSolverBase() { }
[1112]240    //@}
[1081]241
[1112]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:
[1081]252
[1112]253    //UNCATEGORIZED FUNCTIONS
254
[1031]255    /// \e
256    virtual void setMinimize() = 0;
257    /// \e
258    virtual void setMaximize() = 0;
[1081]259
[1112]260    //SOLVER FUNCTIONS
[1081]261
[1112]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
[1241]272    virtual Value getObjVal() = 0;
[1112]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;
[1144]292    /// Returns the status of the slack variable assigned to row \c row.
293    virtual int getRowStat(const Row& row) = 0;
[1112]294    /// \e
295    virtual void printRowStatus(int i) = 0;
[1144]296    /// Returns the status of the variable assigned to column \c col.
297    virtual int getColStat(const Col& col) = 0;
[1112]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    //@{
[1074]307  protected:
[1112]308
309    //MATRIX MANIPULATING FUNCTIONS
310
[1031]311    /// \e
[1111]312    virtual int _addCol() = 0;
313    /// \e
[1074]314    virtual int _addRow() = 0;
[1031]315    /// \e
[1111]316    virtual void _eraseCol(int i) = 0;
317    /// \e
318    virtual void _eraseRow(int i) = 0;
[1081]319    /// \e
320    virtual void _setRowCoeffs(int i,
[1241]321                               const std::vector<std::pair<int, Value> >& coeffs) = 0;
[1081]322    /// \e
[1143]323    /// This routine modifies \c coeffs only by the \c push_back method.
324    virtual void _getRowCoeffs(int i,
[1241]325                               std::vector<std::pair<int, Value> >& coeffs) = 0;
[1152]326    /// \e
[1081]327    virtual void _setColCoeffs(int i,
[1241]328                               const std::vector<std::pair<int, Value> >& coeffs) = 0;
[1143]329    /// \e
330    /// This routine modifies \c coeffs only by the \c push_back method.
331    virtual void _getColCoeffs(int i,
[1241]332                               std::vector<std::pair<int, Value> >& coeffs) = 0;
[1081]333    /// \e
[1241]334    virtual void _setCoeff(int col, int row, Value value) = 0;
[1152]335    /// \e
[1241]336    virtual Value _getCoeff(int col, int row) = 0;
[1152]337    //  public:
338    //    /// \e
339    //    enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
[1081]340  protected:
341    /// \e
[1110]342    /// The lower bound of a variable (column) have to be given by an
[1241]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;
[1110]346    /// \e
[1111]347    /// The lower bound of a variable (column) is an
[1241]348    /// extended number of type Value, i.e. a finite number of type
349    /// Value or -INF.
350    virtual Value _getColLowerBound(int i) = 0;
[1111]351    /// \e
[1110]352    /// The upper bound of a variable (column) have to be given by an
[1241]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;
[1110]356    /// \e
357    /// The upper bound of a variable (column) is an
[1241]358    /// extended number of type Value, i.e. a finite number of type
359    /// Value or INF.
360    virtual Value _getColUpperBound(int i) = 0;
[1110]361    /// \e
[1111]362    /// The lower bound of a linear expression (row) have to be given by an
[1241]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;
[1081]366    /// \e
[1111]367    /// The lower bound of a linear expression (row) is an
[1241]368    /// extended number of type Value, i.e. a finite number of type
369    /// Value or -INF.
370    virtual Value _getRowLowerBound(int i) = 0;
[1111]371    /// \e
372    /// The upper bound of a linear expression (row) have to be given by an
[1241]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;
[1111]376    /// \e
377    /// The upper bound of a linear expression (row) is an
[1241]378    /// extended number of type Value, i.e. a finite number of type
379    /// Value or INF.
380    virtual Value _getRowUpperBound(int i) = 0;
[1081]381    /// \e
[1241]382    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
[1081]383    /// \e
[1241]384    virtual Value _getObjCoeff(int i) = 0;
[1112]385   
386    //SOLUTION RETRIEVING
[1081]387
[1111]388    /// \e
[1241]389    virtual Value _getPrimal(int i) = 0;
[1112]390    //@}
391   
392    /*! @name High level interface (public members)
393      Problem manipulating functions in the high level interface
394    */
395    //@{
396  public:
[1081]397
[1112]398    //MATRIX MANIPULATING FUNCTIONS
[1081]399
[1074]400    /// \e
[1144]401    Col addCol() {
[1074]402      int i=_addCol(); 
[1144]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;
[1074]408      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
[1144]409        col=col_iter_map.push_back(i, VALID_CLASS);
[1074]410      }
[1144]411      int_col_map.push_back(col);
412      return col;
[1074]413    }
414    /// \e
[1144]415    Row addRow() {
[1111]416      int i=_addRow();
[1144]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;
[1111]422      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
[1144]423        row=row_iter_map.push_back(i, VALID_CLASS);
[1031]424      }
[1144]425      int_row_map.push_back(row);
426      return row;
[1074]427    }
428    /// \e
[1144]429    void eraseCol(const Col& col) {
430      col_iter_map.set(col, VALID_CLASS, INVALID_CLASS);
[1074]431      int cols[2];
[1144]432      cols[1]=col_iter_map[col];
[1074]433      _eraseCol(cols[1]);
[1144]434      col_iter_map[col]=0; //glpk specifikus, de kell ez??
435      Col it;
[1074]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      }
[1143]440      int_col_map.erase(int_col_map.begin()+cols[1]);
[1031]441    }
442    /// \e
[1144]443    void eraseRow(const Row& row) {
444      row_iter_map.set(row, VALID_CLASS, INVALID_CLASS);
[1074]445      int rows[2];
[1144]446      rows[1]=row_iter_map[row];
[1074]447      _eraseRow(rows[1]);
[1144]448      row_iter_map[row]=0; //glpk specifikus, de kell ez??
449      Row it;
[1074]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      }
[1143]454      int_row_map.erase(int_row_map.begin()+rows[1]);
[1074]455    }
[1031]456    /// \e
[1241]457    void setCoeff(Col col, Row row, Value value) {
[1152]458      _setCoeff(col_iter_map[col], row_iter_map[row], value);
459    }
460    /// \e
[1241]461    Value getCoeff(Col col, Row row) {
[1152]462      return _getCoeff(col_iter_map[col], row_iter_map[row], value);
463    }
464    /// \e
[1241]465    void setColLowerBound(Col col, Value lo) {
[1144]466      _setColLowerBound(col_iter_map[col], lo);
[1111]467    }
468    /// \e
[1241]469    Value getColLowerBound(Col col) {
[1144]470      return _getColLowerBound(col_iter_map[col]);
[1111]471    }
472    /// \e
[1241]473    void setColUpperBound(Col col, Value up) {
[1144]474      _setColUpperBound(col_iter_map[col], up);
[1110]475    }
476    /// \e
[1241]477    Value getColUpperBound(Col col) {     
[1144]478      return _getColUpperBound(col_iter_map[col]);
[1111]479    }
480    /// \e
[1241]481    void setRowLowerBound(Row row, Value lo) {
[1144]482      _setRowLowerBound(row_iter_map[row], lo);
[1110]483    }
484    /// \e
[1241]485    Value getRowLowerBound(Row row) {
[1144]486      return _getRowLowerBound(row_iter_map[row]);
[1110]487    }
488    /// \e
[1241]489    void setRowUpperBound(Row row, Value up) {
[1144]490      _setRowUpperBound(row_iter_map[row], up);
[1081]491    }
[1031]492    /// \e
[1241]493    Value getRowUpperBound(Row row) {     
[1144]494      return _getRowUpperBound(row_iter_map[row]);
[1111]495    }
496    /// \e
[1241]497    void setObjCoeff(const Col& col, Value obj_coef) {
[1152]498      _setObjCoeff(col_iter_map[col], obj_coef);
[1111]499    }
500    /// \e
[1241]501    Value getObjCoeff(const Col& col) {
[1152]502      return _getObjCoeff(col_iter_map[col]);
[1081]503    }
504
[1112]505    //SOLUTION RETRIEVING FUNCTIONS
506
507    /// \e
[1241]508    Value getPrimal(const Col& col) {
[1144]509      return _getPrimal(col_iter_map[col]);
[1112]510    }   
511
512    //@}
513
514    /*! @name User friend interface
515      Problem manipulating functions in the user friend interface
516    */
517    //@{
518
519    //EXPRESSION TYPES
[1099]520
521    /// \e
[1241]522    typedef Expr<Col, Value> Expression;
[1099]523    /// \e
[1241]524    typedef Expr<Row, Value> DualExpression;
[1144]525    /// \e
[1241]526    typedef Constr<Col, Value> Constraint;
[1112]527
528    //MATRIX MANIPULATING FUNCTIONS
529
[1099]530    /// \e
[1144]531    void setRowCoeffs(Row row, const Expression& expr) {
[1241]532      std::vector<std::pair<int, Value> > row_coeffs;
[1099]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      }
[1144]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;
[1099]553    }
554    /// \e
[1143]555    /// This routine modifies \c expr by only adding to it.
[1144]556    void getRowCoeffs(Row row, Expression& expr) {
[1241]557      std::vector<std::pair<int, Value> > row_coeffs;
[1144]558      _getRowCoeffs(row_iter_map[row], row_coeffs);
[1241]559      for(typename std::vector<std::pair<int, Value> >::const_iterator
[1143]560            i=row_coeffs.begin(); i!=row_coeffs.end(); ++i) {
561        expr+= (*i).second*int_col_map[(*i).first];
562      }
563    }
564    /// \e
[1144]565    void setColCoeffs(Col col, const DualExpression& expr) {
[1241]566      std::vector<std::pair<int, Value> > col_coeffs;
[1099]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      }
[1144]572      _setColCoeffs(col_iter_map[col], col_coeffs);
[1099]573    }
574    /// \e
[1143]575    /// This routine modifies \c expr by only adding to it.
[1144]576    void getColCoeffs(Col col, DualExpression& expr) {
[1241]577      std::vector<std::pair<int, Value> > col_coeffs;
[1144]578      _getColCoeffs(col_iter_map[col], col_coeffs);
[1241]579      for(typename std::vector<std::pair<int, Value> >::const_iterator
[1143]580            i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) {
581        expr+= (*i).second*int_row_map[(*i).first];
582      }
583    }
584    /// \e
[1099]585    void setObjCoeffs(const Expression& expr) {
[1152]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
[1099]590      for(typename Expression::Data::const_iterator i=expr.data.begin();
591          i!=expr.data.end(); ++i) {
[1152]592        setObjCoeff((*i).first, (*i).second);
[1099]593      }
594    }
[1143]595    /// \e
596    /// This routine modifies \c expr by only adding to it.
597    void getObjCoeffs(Expression& expr) {
[1152]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;
[1153]619    /// \e
[1241]620    virtual Value _getMIPPrimal(int i) = 0;
[1152]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]);
[1143]629    }
[1153]630    /// \e
[1241]631    Value getMIPPrimal(Col col) {
[1153]632      return _getMIPPrimal(col_iter_map[col]);
633    }
[1112]634    //@}
[1031]635  };
636
637} //namespace lemon
638
[1152]639#endif //LEMON_LP_SOLVER_BASE_H
Note: See TracBrowser for help on using the repository browser.