src/work/marci/lp/lp_solver_base.h
changeset 1152 1765ff9fefa1
parent 1144 1cfabf245433
child 1153 4b0468de3a31
equal deleted inserted replaced
4:5c774b4e1fcd 5:1d36f03c5a82
     1 // -*- c++ -*-
     1 // -*- c++ -*-
     2 #ifndef LEMON_LP_SOLVER_WRAPPER_H
     2 #ifndef LEMON_LP_SOLVER_BASE_H
     3 #define LEMON_LP_SOLVER_WRAPPER_H
     3 #define LEMON_LP_SOLVER_BASE_H
     4 
     4 
     5 ///\ingroup misc
     5 ///\ingroup misc
     6 ///\file
     6 ///\file
     7 ///\brief Dijkstra algorithm.
       
     8 
     7 
     9 // #include <stdio.h>
     8 // #include <stdio.h>
    10 #include <stdlib.h>
     9 #include <stdlib.h>
    11 #include <iostream>
    10 #include <iostream>
    12 #include <map>
    11 #include <map>
    22 #include <string>
    21 #include <string>
    23 #include <list>
    22 #include <list>
    24 #include <memory>
    23 #include <memory>
    25 #include <utility>
    24 #include <utility>
    26 
    25 
    27 //#include <lemon/list_graph.h>
       
    28 #include <lemon/invalid.h>
    26 #include <lemon/invalid.h>
    29 #include <expression.h>
    27 #include <expression.h>
    30 //#include <bfs_dfs.h>
       
    31 //#include <stp.h>
    28 //#include <stp.h>
    32 //#include <lemon/max_flow.h>
    29 //#include <lemon/max_flow.h>
    33 //#include <augmenting_flow.h>
    30 //#include <augmenting_flow.h>
    34 //#include <iter_map.h>
    31 //#include <iter_map.h>
    35 
    32 
    65     std::vector<Tip> tips;
    62     std::vector<Tip> tips;
    66   public:
    63   public:
    67     /// The classes are indexed by integers from \c 0 to \c classNum()-1.
    64     /// The classes are indexed by integers from \c 0 to \c classNum()-1.
    68     int classNum() const { return tips.size(); }
    65     int classNum() const { return tips.size(); }
    69     /// This lemon style iterator iterates through a class. 
    66     /// This lemon style iterator iterates through a class. 
    70     class ClassIt;
    67     class Class;
    71     /// Constructor. The number of classes is to be given which is fixed 
    68     /// Constructor. The number of classes is to be given which is fixed 
    72     /// over the life of the container. 
    69     /// over the life of the container. 
    73     /// The partition classes are indexed from 0 to class_num-1. 
    70     /// The partition classes are indexed from 0 to class_num-1. 
    74     IterablePartition(int class_num) { 
    71     IterablePartition(int class_num) { 
    75       for (int i=0; i<class_num; ++i) {
    72       for (int i=0; i<class_num; ++i) {
    77 	t.first=t.last=-1;
    74 	t.first=t.last=-1;
    78 	tips.push_back(t);
    75 	tips.push_back(t);
    79       }
    76       }
    80     }
    77     }
    81   protected:
    78   protected:
    82     void befuz(ClassIt it, int class_id) {
    79     void befuz(Class it, int class_id) {
    83       if (tips[class_id].first==-1) {
    80       if (tips[class_id].first==-1) {
    84 	if (tips[class_id].last==-1) {
    81 	if (tips[class_id].last==-1) {
    85 	  nodes[it.i].prev=nodes[it.i].next=-1;
    82 	  nodes[it.i].prev=nodes[it.i].next=-1;
    86 	  tips[class_id].first=tips[class_id].last=it.i;
    83 	  tips[class_id].first=tips[class_id].last=it.i;
    87 	}
    84 	}
    90 	nodes[it.i].next=-1;
    87 	nodes[it.i].next=-1;
    91 	nodes[tips[class_id].last].next=it.i;
    88 	nodes[tips[class_id].last].next=it.i;
    92 	tips[class_id].last=it.i;
    89 	tips[class_id].last=it.i;
    93       }
    90       }
    94     }
    91     }
    95     void kifuz(ClassIt it, int class_id) {
    92     void kifuz(Class it, int class_id) {
    96       if (tips[class_id].first==it.i) {
    93       if (tips[class_id].first==it.i) {
    97 	if (tips[class_id].last==it.i) {
    94 	if (tips[class_id].last==it.i) {
    98 	  tips[class_id].first=tips[class_id].last=-1;
    95 	  tips[class_id].first=tips[class_id].last=-1;
    99 	} else {
    96 	} else {
   100 	  tips[class_id].first=nodes[it.i].next;
    97 	  tips[class_id].first=nodes[it.i].next;
   111       }
   108       }
   112     }
   109     }
   113   public:
   110   public:
   114     /// A new element with data \c t is pushed into the vector and into class 
   111     /// A new element with data \c t is pushed into the vector and into class 
   115     /// \c class_id.
   112     /// \c class_id.
   116     ClassIt push_back(const T& t, int class_id) { 
   113     Class push_back(const T& t, int class_id) { 
   117       Node n;
   114       Node n;
   118       n.data=t;
   115       n.data=t;
   119       nodes.push_back(n);
   116       nodes.push_back(n);
   120       int i=nodes.size()-1;
   117       int i=nodes.size()-1;
   121       befuz(i, class_id);
   118       befuz(i, class_id);
   122       return i;
   119       return i;
   123     }
   120     }
   124     /// A member is moved to an other class.
   121     /// A member is moved to an other class.
   125     void set(ClassIt it, int old_class_id, int new_class_id) {
   122     void set(Class it, int old_class_id, int new_class_id) {
   126       kifuz(it.i, old_class_id);
   123       kifuz(it.i, old_class_id);
   127       befuz(it.i, new_class_id);
   124       befuz(it.i, new_class_id);
   128     }
   125     }
   129     /// Returns the data pointed by \c it.
   126     /// Returns the data pointed by \c it.
   130     T& operator[](ClassIt it) { return nodes[it.i].data; }
   127     T& operator[](Class it) { return nodes[it.i].data; }
   131     /// Returns the data pointed by \c it.
   128     /// Returns the data pointed by \c it.
   132     const T& operator[](ClassIt it) const { return nodes[it.i].data; }
   129     const T& operator[](Class it) const { return nodes[it.i].data; }
   133     ///.
   130     ///.
   134     class ClassIt {
   131     class Class {
   135       friend class IterablePartition;
   132       friend class IterablePartition;
   136     protected:
   133     protected:
   137       int i;
   134       int i;
   138     public:
   135     public:
   139       /// Default constructor.
   136       /// Default constructor.
   140       ClassIt() { }
   137       Class() { }
   141       /// This constructor constructs an iterator which points
   138       /// This constructor constructs an iterator which points
   142       /// to the member of th container indexed by the integer _i.
   139       /// to the member of th container indexed by the integer _i.
   143       ClassIt(const int& _i) : i(_i) { }
   140       Class(const int& _i) : i(_i) { }
   144       /// Invalid constructor.
   141       /// Invalid constructor.
   145       ClassIt(const Invalid&) : i(-1) { }
   142       Class(const Invalid&) : i(-1) { }
   146       friend bool operator<(const ClassIt& x, const ClassIt& y);
   143       friend bool operator<(const Class& x, const Class& y);
   147       friend std::ostream& operator<<(std::ostream& os, 
   144       friend std::ostream& operator<<(std::ostream& os, 
   148 				      const ClassIt& it);
   145 				      const Class& it);
       
   146       bool operator==(const Class& node) const {return i == node.i;}
       
   147       bool operator!=(const Class& node) const {return i != node.i;}
   149     };
   148     };
   150     friend bool operator<(const ClassIt& x, const ClassIt& y) {
   149     friend bool operator<(const Class& x, const Class& y) {
   151       return (x.i < y.i);
   150       return (x.i < y.i);
   152     }
   151     }
   153     friend std::ostream& operator<<(std::ostream& os, 
   152     friend std::ostream& operator<<(std::ostream& os, 
   154 				    const ClassIt& it) {
   153 				    const Class& it) {
   155       os << it.i;
   154       os << it.i;
   156       return os;
   155       return os;
   157     }
   156     }
   158     /// First member of class \c class_id.
   157     /// First member of class \c class_id.
   159     ClassIt& first(ClassIt& it, int class_id) const {
   158     Class& first(Class& it, int class_id) const {
   160       it.i=tips[class_id].first;
   159       it.i=tips[class_id].first;
   161       return it;
   160       return it;
   162     }
   161     }
   163     /// Next member.
   162     /// Next member.
   164     ClassIt& next(ClassIt& it) const {
   163     Class& next(Class& it) const {
   165       it.i=nodes[it.i].next;
   164       it.i=nodes[it.i].next;
   166       return it;
   165       return it;
   167     }
   166     }
   168     /// True iff the iterator is valid.
   167     /// True iff the iterator is valid.
   169     bool valid(const ClassIt& it) const { return it.i!=-1; }
   168     bool valid(const Class& it) const { return it.i!=-1; }
       
   169 
       
   170     class ClassIt : public Class {
       
   171       const IterablePartition* iterable_partition;
       
   172     public:
       
   173       ClassIt() { }
       
   174       ClassIt(Invalid i) : Class(i) { }
       
   175       ClassIt(const IterablePartition& _iterable_partition, 
       
   176 	      const int& i) : iterable_partition(&_iterable_partition) {
       
   177         _iterable_partition.first(*this, i);
       
   178       }
       
   179       ClassIt(const IterablePartition& _iterable_partition, 
       
   180 	      const Class& _class) : 
       
   181 	Class(_class), iterable_partition(&_iterable_partition) { }
       
   182       ClassIt& operator++() {
       
   183         iterable_partition->next(*this);
       
   184         return *this;
       
   185       }
       
   186     };
       
   187 
   170   };
   188   };
   171 
   189 
   172 
   190 
   173   /*! \e
   191   /*! \e
   174     \todo kellenene uj iterable structure bele, mert ez nem az igazi
   192     \todo kellenene uj iterable structure bele, mert ez nem az igazi
   189   public:
   207   public:
   190 
   208 
   191     //UNCATEGORIZED
   209     //UNCATEGORIZED
   192 
   210 
   193     /// \e
   211     /// \e
       
   212     typedef IterablePartition<int> Rows;
       
   213     /// \e
       
   214     typedef IterablePartition<int> Cols;
       
   215     /// \e
   194     typedef _Value Value;
   216     typedef _Value Value;
   195     /// \e
   217     /// \e
   196     typedef IterablePartition<int>::ClassIt Row;
   218     typedef Rows::Class Row;
   197     /// \e
   219     /// \e
   198     typedef IterablePartition<int>::ClassIt Col;
   220     typedef Cols::Class Col;
   199   public:
   221   public:
   200     /// \e
   222     /// \e
   201     IterablePartition<int> row_iter_map;
   223     IterablePartition<int> row_iter_map;
   202     /// \e
   224     /// \e
   203     IterablePartition<int> col_iter_map;
   225     IterablePartition<int> col_iter_map;
   244     virtual void solveSimplex() = 0;
   266     virtual void solveSimplex() = 0;
   245     /// \e
   267     /// \e
   246     virtual void solvePrimalSimplex() = 0;
   268     virtual void solvePrimalSimplex() = 0;
   247     /// \e
   269     /// \e
   248     virtual void solveDualSimplex() = 0;
   270     virtual void solveDualSimplex() = 0;
   249     /// \e
       
   250 
   271 
   251     //SOLUTION RETRIEVING
   272     //SOLUTION RETRIEVING
   252 
   273 
   253     /// \e
   274     /// \e
   254     virtual _Value getObjVal() = 0;
   275     virtual _Value getObjVal() = 0;
   303 			       const std::vector<std::pair<int, _Value> >& coeffs) = 0;
   324 			       const std::vector<std::pair<int, _Value> >& coeffs) = 0;
   304     /// \e
   325     /// \e
   305     /// This routine modifies \c coeffs only by the \c push_back method.
   326     /// This routine modifies \c coeffs only by the \c push_back method.
   306     virtual void _getRowCoeffs(int i, 
   327     virtual void _getRowCoeffs(int i, 
   307 			       std::vector<std::pair<int, _Value> >& coeffs) = 0;
   328 			       std::vector<std::pair<int, _Value> >& coeffs) = 0;
       
   329     /// \e
   308     virtual void _setColCoeffs(int i, 
   330     virtual void _setColCoeffs(int i, 
   309 			       const std::vector<std::pair<int, _Value> >& coeffs) = 0;
   331 			       const std::vector<std::pair<int, _Value> >& coeffs) = 0;
   310     /// \e
   332     /// \e
   311     /// This routine modifies \c coeffs only by the \c push_back method.
   333     /// This routine modifies \c coeffs only by the \c push_back method.
   312     virtual void _getColCoeffs(int i, 
   334     virtual void _getColCoeffs(int i, 
   313 			       std::vector<std::pair<int, _Value> >& coeffs) = 0;
   335 			       std::vector<std::pair<int, _Value> >& coeffs) = 0;
   314   public:
   336     /// \e
   315     /// \e
   337     virtual void _setCoeff(int col, int row, _Value value) = 0;
   316     enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
   338     /// \e
       
   339     virtual _Value _getCoeff(int col, int row) = 0;
       
   340     //  public:
       
   341     //    /// \e
       
   342     //    enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
   317   protected:
   343   protected:
   318     /// \e
   344     /// \e
   319     /// The lower bound of a variable (column) have to be given by an 
   345     /// The lower bound of a variable (column) have to be given by an 
   320     /// extended number of type _Value, i.e. a finite number of type 
   346     /// extended number of type _Value, i.e. a finite number of type 
   321     /// _Value or -INF.
   347     /// _Value or -INF.
   354     /// The upper bound of a linear expression (row) is an 
   380     /// The upper bound of a linear expression (row) is an 
   355     /// extended number of type _Value, i.e. a finite number of type 
   381     /// extended number of type _Value, i.e. a finite number of type 
   356     /// _Value or INF.
   382     /// _Value or INF.
   357     virtual _Value _getRowUpperBound(int i) = 0;
   383     virtual _Value _getRowUpperBound(int i) = 0;
   358     /// \e
   384     /// \e
   359     virtual void _setObjCoef(int i, _Value obj_coef) = 0;
   385     virtual void _setObjCoeff(int i, _Value obj_coef) = 0;
   360     /// \e
   386     /// \e
   361     virtual _Value _getObjCoef(int i) = 0;
   387     virtual _Value _getObjCoeff(int i) = 0;
   362     
   388     
   363     //SOLUTION RETRIEVING
   389     //SOLUTION RETRIEVING
   364 
   390 
   365     /// \e
   391     /// \e
   366     virtual _Value _getPrimal(int i) = 0;
   392     virtual _Value _getPrimal(int i) = 0;
   429 	if (row_iter_map[it]>rows[1]) --row_iter_map[it];
   455 	if (row_iter_map[it]>rows[1]) --row_iter_map[it];
   430       }
   456       }
   431       int_row_map.erase(int_row_map.begin()+rows[1]);
   457       int_row_map.erase(int_row_map.begin()+rows[1]);
   432     }
   458     }
   433     /// \e
   459     /// \e
       
   460     void setCoeff(Col col, Row row, _Value value) {
       
   461       _setCoeff(col_iter_map[col], row_iter_map[row], value);
       
   462     }
       
   463     /// \e
       
   464     _Value getCoeff(Col col, Row row) {
       
   465       return _getCoeff(col_iter_map[col], row_iter_map[row], value);
       
   466     }
       
   467     /// \e
   434     void setColLowerBound(Col col, _Value lo) {
   468     void setColLowerBound(Col col, _Value lo) {
   435       _setColLowerBound(col_iter_map[col], lo);
   469       _setColLowerBound(col_iter_map[col], lo);
   436     }
   470     }
   437     /// \e
   471     /// \e
   438     _Value getColLowerBound(Col col) {
   472     _Value getColLowerBound(Col col) {
   461     /// \e
   495     /// \e
   462     _Value getRowUpperBound(Row row) {      
   496     _Value getRowUpperBound(Row row) {      
   463       return _getRowUpperBound(row_iter_map[row]);
   497       return _getRowUpperBound(row_iter_map[row]);
   464     }
   498     }
   465     /// \e
   499     /// \e
   466     void setObjCoef(const Col& col, _Value obj_coef) {
   500     void setObjCoeff(const Col& col, _Value obj_coef) {
   467       _setObjCoef(col_iter_map[col], obj_coef);
   501       _setObjCoeff(col_iter_map[col], obj_coef);
   468     }
   502     }
   469     /// \e
   503     /// \e
   470     _Value getObjCoef(const Col& col) {
   504     _Value getObjCoeff(const Col& col) {
   471       return _getObjCoef(col_iter_map[col]);
   505       return _getObjCoeff(col_iter_map[col]);
   472     }
   506     }
   473 
   507 
   474     //SOLUTION RETRIEVING FUNCTIONS
   508     //SOLUTION RETRIEVING FUNCTIONS
   475 
   509 
   476     /// \e
   510     /// \e
   549  	    i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) {
   583  	    i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) {
   550  	expr+= (*i).second*int_row_map[(*i).first];
   584  	expr+= (*i).second*int_row_map[(*i).first];
   551       }
   585       }
   552     }
   586     }
   553     /// \e
   587     /// \e
   554     /// \bug ez igy nem jo
       
   555     void setObjCoeffs(const Expression& expr) {
   588     void setObjCoeffs(const Expression& expr) {
       
   589       // writing zero everywhere
       
   590       for(Cols::ClassIt it(col_iter_map, VALID_CLASS); it!=INVALID; ++it)
       
   591 	setObjCoeff(it, 0.0);
       
   592       // writing the data needed
   556       for(typename Expression::Data::const_iterator i=expr.data.begin(); 
   593       for(typename Expression::Data::const_iterator i=expr.data.begin(); 
   557 	  i!=expr.data.end(); ++i) {
   594 	  i!=expr.data.end(); ++i) {
   558 	setObjCoef((*i).first, (*i).second);
   595 	setObjCoeff((*i).first, (*i).second);
   559       }
   596       }
   560     }
   597     }
   561     /// \e
   598     /// \e
   562     /// This routine modifies \c expr by only adding to it.
   599     /// This routine modifies \c expr by only adding to it.
   563     void getObjCoeffs(Expression& expr) {
   600     void getObjCoeffs(Expression& expr) {
   564       /// FIXME not yet implemented
   601       for(Cols::ClassIt it(col_iter_map, VALID_CLASS); it!=INVALID; ++it)
       
   602 	expr+=getObjCoeff(it)*it;
       
   603     }
       
   604     //@}
       
   605 
       
   606 
       
   607     /*! @name MIP functions and types (public members)
       
   608     */
       
   609     //@{
       
   610   public:
       
   611     /// \e
       
   612     virtual void solveBandB() = 0;
       
   613     /// \e
       
   614     virtual void setLP() = 0;
       
   615     /// \e
       
   616     virtual void setMIP() = 0;
       
   617   protected:
       
   618    /// \e
       
   619     virtual void _setColCont(int i) = 0;
       
   620     /// \e
       
   621     virtual void _setColInt(int i) = 0;
       
   622   public:
       
   623     /// \e
       
   624     void setColCont(Col col) {
       
   625       _setColCont(col_iter_map[col]);
       
   626     }
       
   627     /// \e
       
   628     void setColInt(Col col) {
       
   629       _setColInt(col_iter_map[col]);
   565     }
   630     }
   566     //@}
   631     //@}
   567   };
   632   };
   568   
   633   
   569   template <typename _Value>
   634   template <typename _Value>
   688     }
   753     }
   689     virtual void _eraseRow(int i) {
   754     virtual void _eraseRow(int i) {
   690       int rows[2];
   755       int rows[2];
   691       rows[1]=i;
   756       rows[1]=i;
   692       lpx_del_rows(lp, 1, rows);
   757       lpx_del_rows(lp, 1, rows);
       
   758     }
       
   759     void _setCoeff(int col, int row, double value) {
       
   760       /// FIXME not yet implemented
       
   761     }
       
   762     double _getCoeff(int col, int row) {
       
   763       /// FIXME not yet implemented
       
   764       return 0.0;
   693     }
   765     }
   694     virtual void _setColLowerBound(int i, double lo) {
   766     virtual void _setColLowerBound(int i, double lo) {
   695       if (lo==INF) {
   767       if (lo==INF) {
   696 	//FIXME error
   768 	//FIXME error
   697       }
   769       }
   926 	//FIXME error
   998 	//FIXME error
   927 	return 0.0;
   999 	return 0.0;
   928       }
  1000       }
   929     }
  1001     }
   930     /// \e
  1002     /// \e
   931     virtual double _getObjCoef(int i) { 
  1003     virtual double _getObjCoeff(int i) { 
   932       return lpx_get_obj_coef(lp, i);
  1004       return lpx_get_obj_coef(lp, i);
   933     }
  1005     }
   934     /// \e
  1006     /// \e
   935     virtual void _setObjCoef(int i, double obj_coef) { 
  1007     virtual void _setObjCoeff(int i, double obj_coef) { 
   936       lpx_set_obj_coef(lp, i, obj_coef);
  1008       lpx_set_obj_coef(lp, i, obj_coef);
   937     }
  1009     }
   938   public:
  1010   public:
   939     /// \e
  1011     /// \e
   940     void solveSimplex() { lpx_simplex(lp); }
  1012     void solveSimplex() { lpx_simplex(lp); }
   941     /// \e
  1013     /// \e
   942     void solvePrimalSimplex() { lpx_simplex(lp); }
  1014     void solvePrimalSimplex() { lpx_simplex(lp); }
   943     /// \e
  1015     /// \e
   944     void solveDualSimplex() { lpx_simplex(lp); }
  1016     void solveDualSimplex() { lpx_simplex(lp); }
   945     /// \e
       
   946   protected:
  1017   protected:
   947     virtual double _getPrimal(int i) {
  1018     virtual double _getPrimal(int i) {
   948       return lpx_get_col_prim(lp, i);
  1019       return lpx_get_col_prim(lp, i);
   949     }
  1020     }
   950   public:
  1021   public:
  1013       case LPX_NU: cout << "LPX_NU" << endl; break;
  1084       case LPX_NU: cout << "LPX_NU" << endl; break;
  1014       case LPX_NF: cout << "LPX_NF" << endl; break;
  1085       case LPX_NF: cout << "LPX_NF" << endl; break;
  1015       case LPX_NS: cout << "LPX_NS" << endl; break;
  1086       case LPX_NS: cout << "LPX_NS" << endl; break;
  1016       }
  1087       }
  1017     }
  1088     }
       
  1089 
       
  1090     // MIP
       
  1091     /// \e
       
  1092     void solveBandB() { lpx_integer(lp); }
       
  1093     /// \e
       
  1094     void setLP() { lpx_set_class(lp, LPX_LP); }
       
  1095     /// \e
       
  1096     void setMIP() { lpx_set_class(lp, LPX_MIP); }
       
  1097   protected:
       
  1098     /// \e
       
  1099     void _setColCont(int i) {lpx_set_col_kind(lp, i, LPX_CV); }
       
  1100     /// \e
       
  1101     void _setColInt(int i) {lpx_set_col_kind(lp, i, LPX_IV); }
  1018   };
  1102   };
  1019   
  1103   
  1020   /// @}
  1104   /// @}
  1021 
  1105 
  1022 } //namespace lemon
  1106 } //namespace lemon
  1023 
  1107 
  1024 #endif //LEMON_LP_SOLVER_WRAPPER_H
  1108 #endif //LEMON_LP_SOLVER_BASE_H