src/lemon/lp_base.h
changeset 1364 ee5959aa4410
parent 1359 1581f961cfaa
child 1376 8de0c1aeeb32
equal deleted inserted replaced
4:eccf9d58a025 5:0cb95bdeef56
   196     ///(\ref Col "Col"s) and also has a constant component.
   196     ///(\ref Col "Col"s) and also has a constant component.
   197     ///
   197     ///
   198     ///There are several ways to access and modify the contents of this
   198     ///There are several ways to access and modify the contents of this
   199     ///container.
   199     ///container.
   200     ///- Its it fully compatible with \c std::map<Col,double>, so for expamle
   200     ///- Its it fully compatible with \c std::map<Col,double>, so for expamle
   201     ///if \c e is an Expr and \c v and \c w are of type \ref Col then you can
   201     ///if \c e is an Expr and \c v and \c w are of type \ref Col, then you can
   202     ///read and modify the coefficients like
   202     ///read and modify the coefficients like
   203     ///these.
   203     ///these.
   204     ///\code
   204     ///\code
   205     ///e[v]=5;
   205     ///e[v]=5;
   206     ///e[v]+=12;
   206     ///e[v]+=12;
   316       }
   316       }
   317     };
   317     };
   318     
   318     
   319     ///Linear constraint
   319     ///Linear constraint
   320 
   320 
   321     ///\todo document please
   321     ///This data stucture represents a linear constraint in the LP.
   322     ///
   322     ///Basically it is a linear expression with a lower or an upper bound
       
   323     ///(or both). These parts of the constraint can be obtained by the member
       
   324     ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
       
   325     ///respectively.
       
   326     ///There are two ways to construct a constraint.
       
   327     ///- You can set the linear expression and the bounds directly
       
   328     ///  by the functions above.
       
   329     ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
       
   330     ///  are defined between expressions, or even between constraints whenever
       
   331     ///  it makes sense. Therefore if \c e and \c f are linear expressions and
       
   332     ///  \c s and \c t are numbers, then the followings are valid expressions
       
   333     ///  and thus they can be used directly e.g. in \ref addRow() whenever
       
   334     ///  it makes sense.
       
   335     ///  \code
       
   336     ///  e<=s
       
   337     ///  e<=f
       
   338     ///  s<=e<=t
       
   339     ///  e>=t
       
   340     ///  \endcode
       
   341     ///\warning The validity of a constraint is checked only at run time, so
       
   342     ///e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will compile, but will throw a
       
   343     ///\ref LogicError exception.
   323     class Constr
   344     class Constr
   324     {
   345     {
   325     public:
   346     public:
   326       typedef LpSolverBase::Expr Expr;
   347       typedef LpSolverBase::Expr Expr;
   327       typedef Expr::Key Key;
   348       typedef Expr::Key Key;
   328       typedef Expr::Value Value;
   349       typedef Expr::Value Value;
   329       
   350       
   330       static const Value INF;
   351 //       static const Value INF;
   331       static const Value NaN;
   352 //       static const Value NaN;
   332       //     static const Value INF=0;
   353 
   333       //     static const Value NaN=1;
       
   334       
       
   335     protected:
   354     protected:
   336       Expr _expr;
   355       Expr _expr;
   337       Value _lb,_ub;
   356       Value _lb,_ub;
   338     public:
   357     public:
   339       ///\e
   358       ///\e
   354       void clear() 
   373       void clear() 
   355       {
   374       {
   356 	_expr.clear();
   375 	_expr.clear();
   357 	_lb=_ub=NaN;
   376 	_lb=_ub=NaN;
   358       }
   377       }
   359       ///\e
   378 
       
   379       ///Reference to the linear expression 
   360       Expr &expr() { return _expr; }
   380       Expr &expr() { return _expr; }
   361       ///\e
   381       ///Cont reference to the linear expression 
   362       const Expr &expr() const { return _expr; }
   382       const Expr &expr() const { return _expr; }
   363       ///\e
   383       ///Reference to the lower bound.
       
   384 
       
   385       ///\return
       
   386       ///- -\ref INF: the constraint is lower unbounded.
       
   387       ///- -\ref NaN: lower bound has not been set.
       
   388       ///- finite number: the lower bound
   364       Value &lowerBound() { return _lb; }
   389       Value &lowerBound() { return _lb; }
   365       ///\e
   390       ///The const version of \ref lowerBound()
   366       const Value &lowerBound() const { return _lb; }
   391       const Value &lowerBound() const { return _lb; }
   367       ///\e
   392       ///Reference to the upper bound.
       
   393 
       
   394       ///\return
       
   395       ///- -\ref INF: the constraint is upper unbounded.
       
   396       ///- -\ref NaN: upper bound has not been set.
       
   397       ///- finite number: the upper bound
   368       Value &upperBound() { return _ub; }
   398       Value &upperBound() { return _ub; }
   369       ///\e
   399       ///The const version of \ref upperBound()
   370       const Value &upperBound() const { return _ub; }
   400       const Value &upperBound() const { return _ub; }
   371       ///\e
   401       ///Is the constraint lower bounded?
   372       bool lowerBounded() const { 
   402       bool lowerBounded() const { 
   373 	using namespace std;
   403 	using namespace std;
   374 	return isfinite(_lb);
   404 	return isfinite(_lb);
   375       }
   405       }
   376       ///\e
   406       ///Is the constraint upper bounded?
   377       bool upperBounded() const {
   407       bool upperBounded() const {
   378 	using namespace std;
   408 	using namespace std;
   379 	return isfinite(_ub);
   409 	return isfinite(_ub);
   380       }
   410       }
   381     };
   411     };
   384   protected:
   414   protected:
   385     _FixId rows;
   415     _FixId rows;
   386     _FixId cols;
   416     _FixId cols;
   387 
   417 
   388     //Abstract virtual functions
   418     //Abstract virtual functions
       
   419     virtual LpSolverBase &_newLp() = 0;
       
   420     virtual LpSolverBase &_copyLp() = 0;
       
   421 
   389     virtual int _addCol() = 0;
   422     virtual int _addCol() = 0;
   390     virtual int _addRow() = 0;
   423     virtual int _addRow() = 0;
   391     virtual void _setRowCoeffs(int i, 
   424     virtual void _setRowCoeffs(int i, 
   392 			       int length,
   425 			       int length,
   393                                int  const * indices, 
   426                                int  const * indices, 
   424     LpSolverBase() : obj_const_comp(0) {}
   457     LpSolverBase() : obj_const_comp(0) {}
   425 
   458 
   426     ///\e
   459     ///\e
   427     virtual ~LpSolverBase() {}
   460     virtual ~LpSolverBase() {}
   428 
   461 
       
   462     ///Creates a new LP problem
       
   463     LpSolverBase &newLp() {return _newLp();}
       
   464     ///Make a copy of the LP problem
       
   465     LpSolverBase &copyLp() {return _copyLp();}
       
   466     
   429     ///\name Build up and modify of the LP
   467     ///\name Build up and modify of the LP
   430 
   468 
   431     ///@{
   469     ///@{
   432 
   470 
   433     ///Add a new empty column (i.e a new variable) to the LP
   471     ///Add a new empty column (i.e a new variable) to the LP
   449     ///\endcode
   487     ///\endcode
   450     ///- a standard STL compatible iterable container with
   488     ///- a standard STL compatible iterable container with
   451     ///\ref Col as its \c mapped_type
   489     ///\ref Col as its \c mapped_type
   452     ///like
   490     ///like
   453     ///\code
   491     ///\code
   454     ///std::map<AnyStatus,LpSolverBase::Col>
   492     ///std::map<AnyType,LpSolverBase::Col>
   455     ///\endcode
   493     ///\endcode
   456     ///- an iterable lemon \ref concept::WriteMap "write map" like 
   494     ///- an iterable lemon \ref concept::WriteMap "write map" like 
   457     ///\code
   495     ///\code
   458     ///ListGraph::NodeMap<LpSolverBase::Col>
   496     ///ListGraph::NodeMap<LpSolverBase::Col>
   459     ///ListGraph::EdgeMap<LpSolverBase::Col>
   497     ///ListGraph::EdgeMap<LpSolverBase::Col>
   460     ///\endcode
   498     ///\endcode
   461     ///\return The number of the created column.
   499     ///\return The number of the created column.
   462     ///\bug Iterable nodemap hasn't been implemented yet.
       
   463 #ifdef DOXYGEN
   500 #ifdef DOXYGEN
   464     template<class T>
   501     template<class T>
   465     int addColSet(T &t) { return 0;} 
   502     int addColSet(T &t) { return 0;} 
   466 #else
   503 #else
   467     template<class T>
   504     template<class T>
   666     ///\e
   703     ///\e
   667 
   704 
   668     ///\return
   705     ///\return
   669     ///- \ref INF or -\ref INF means either infeasibility or unboundedness
   706     ///- \ref INF or -\ref INF means either infeasibility or unboundedness
   670     /// of the primal problem, depending on whether we minimize or maximize.
   707     /// of the primal problem, depending on whether we minimize or maximize.
   671     ///- \ref NAN if no primal solution is found.
   708     ///- \ref NaN if no primal solution is found.
   672     ///- The (finite) objective value if an optimal solution is found.
   709     ///- The (finite) objective value if an optimal solution is found.
   673     Value primalValue() { return _getPrimalValue()+obj_const_comp;}
   710     Value primalValue() { return _getPrimalValue()+obj_const_comp;}
   674     ///@}
   711     ///@}
   675     
   712     
   676   };  
   713   };  
   681   ///
   718   ///
   682   inline LpSolverBase::Expr operator+(const LpSolverBase::Expr &a,
   719   inline LpSolverBase::Expr operator+(const LpSolverBase::Expr &a,
   683 				      const LpSolverBase::Expr &b) 
   720 				      const LpSolverBase::Expr &b) 
   684   {
   721   {
   685     LpSolverBase::Expr tmp(a);
   722     LpSolverBase::Expr tmp(a);
   686     tmp+=b; ///\todo Don't STL have some special 'merge' algorithm?
   723     tmp+=b; ///\todo Doesn't STL have some special 'merge' algorithm?
   687     return tmp;
   724     return tmp;
   688   }
   725   }
   689   ///\e
   726   ///\e
   690   
   727   
   691   ///\relates LpSolverBase::Expr
   728   ///\relates LpSolverBase::Expr
   692   ///
   729   ///
   693   inline LpSolverBase::Expr operator-(const LpSolverBase::Expr &a,
   730   inline LpSolverBase::Expr operator-(const LpSolverBase::Expr &a,
   694 				      const LpSolverBase::Expr &b) 
   731 				      const LpSolverBase::Expr &b) 
   695   {
   732   {
   696     LpSolverBase::Expr tmp(a);
   733     LpSolverBase::Expr tmp(a);
   697     tmp-=b; ///\todo Don't STL have some special 'merge' algorithm?
   734     tmp-=b; ///\todo Doesn't STL have some special 'merge' algorithm?
   698     return tmp;
   735     return tmp;
   699   }
   736   }
   700   ///\e
   737   ///\e
   701   
   738   
   702   ///\relates LpSolverBase::Expr
   739   ///\relates LpSolverBase::Expr
   703   ///
   740   ///
   704   inline LpSolverBase::Expr operator*(const LpSolverBase::Expr &a,
   741   inline LpSolverBase::Expr operator*(const LpSolverBase::Expr &a,
   705 				      const LpSolverBase::Value &b) 
   742 				      const LpSolverBase::Value &b) 
   706   {
   743   {
   707     LpSolverBase::Expr tmp(a);
   744     LpSolverBase::Expr tmp(a);
   708     tmp*=b; ///\todo Don't STL have some special 'merge' algorithm?
   745     tmp*=b; ///\todo Doesn't STL have some special 'merge' algorithm?
   709     return tmp;
   746     return tmp;
   710   }
   747   }
   711   
   748   
   712   ///\e
   749   ///\e
   713   
   750   
   715   ///
   752   ///
   716   inline LpSolverBase::Expr operator*(const LpSolverBase::Value &a,
   753   inline LpSolverBase::Expr operator*(const LpSolverBase::Value &a,
   717 				      const LpSolverBase::Expr &b) 
   754 				      const LpSolverBase::Expr &b) 
   718   {
   755   {
   719     LpSolverBase::Expr tmp(b);
   756     LpSolverBase::Expr tmp(b);
   720     tmp*=a; ///\todo Don't STL have some special 'merge' algorithm?
   757     tmp*=a; ///\todo Doesn't STL have some special 'merge' algorithm?
   721     return tmp;
   758     return tmp;
   722   }
   759   }
   723   ///\e
   760   ///\e
   724   
   761   
   725   ///\relates LpSolverBase::Expr
   762   ///\relates LpSolverBase::Expr
   726   ///
   763   ///
   727   inline LpSolverBase::Expr operator/(const LpSolverBase::Expr &a,
   764   inline LpSolverBase::Expr operator/(const LpSolverBase::Expr &a,
   728 				      const LpSolverBase::Value &b) 
   765 				      const LpSolverBase::Value &b) 
   729   {
   766   {
   730     LpSolverBase::Expr tmp(a);
   767     LpSolverBase::Expr tmp(a);
   731     tmp/=b; ///\todo Don't STL have some special 'merge' algorithm?
   768     tmp/=b; ///\todo Doesn't STL have some special 'merge' algorithm?
   732     return tmp;
   769     return tmp;
   733   }
   770   }
   734   
   771   
   735   ///\e
   772   ///\e
   736   
   773