Bug fix.
Default assign operator should be
overrided by that calls the template
assign operator.
     2  * lemon/lp_base.h - Part of LEMON, a generic C++ optimization library
 
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
     7  * Permission to use, modify and distribute this software is granted
 
     8  * provided that this copyright notice appears in all copies. For
 
     9  * precise terms see the accompanying LICENSE file.
 
    11  * This software is provided "AS IS" with no warranty of any kind,
 
    12  * express or implied, and with no claim as to its suitability for any
 
    17 #ifndef LEMON_LP_BASE_H
 
    18 #define LEMON_LP_BASE_H
 
    25 #include<lemon/utility.h>
 
    26 #include<lemon/error.h>
 
    27 #include<lemon/invalid.h>
 
    30 ///\brief The interface of the LP solver interface.
 
    31 ///\ingroup gen_opt_group
 
    34   ///Internal data structure to convert floating id's to fix one's
 
    36   ///\todo This might be implemented to be also usable in other places.
 
    39     std::vector<int> index;
 
    40     std::vector<int> cross;
 
    43     _FixId() : first_free(-1) {};
 
    44     ///Convert a floating id to a fix one
 
    46     ///\param n is a floating id
 
    47     ///\return the corresponding fix id
 
    48     int fixId(int n) const {return cross[n];}
 
    49     ///Convert a fix id to a floating one
 
    51     ///\param n is a fix id
 
    52     ///\return the corresponding floating id
 
    53     int floatingId(int n) const { return index[n];}
 
    54     ///Add a new floating id.
 
    56     ///\param n is a floating id
 
    57     ///\return the fix id of the new value
 
    58     ///\todo Multiple additions should also be handled.
 
    61       if(n>=int(cross.size())) {
 
    64 	  cross[n]=index.size();
 
    69 	  int next=index[first_free];
 
    75       ///\todo Create an own exception type.
 
    76       else throw LogicError(); //floatingId-s must form a continuous range;
 
    80     ///\param n is a fix id
 
    87       for(int i=fl+1;i<int(cross.size());++i) {
 
    93     ///An upper bound on the largest fix id.
 
    95     ///\todo Do we need this?
 
    97     std::size_t maxFixId() { return cross.size()-1; }
 
   101   ///Common base class for LP solvers
 
   103   ///\todo Much more docs
 
   104   ///\ingroup gen_opt_group
 
   109     ///Possible outcomes of an LP solving procedure
 
   110     enum SolveExitStatus {
 
   111       ///This means that the problem has been successfully solved: either
 
   112       ///an optimal solution has been found or infeasibility/unboundedness
 
   115       ///Any other case (including the case when some user specified limit has been exceeded)
 
   120     enum SolutionStatus {
 
   121       ///Feasible solution has'n been found (but may exist).
 
   123       ///\todo NOTFOUND might be a better name.
 
   126       ///The problem has no feasible solution
 
   128       ///Feasible solution found
 
   130       ///Optimal solution exists and found
 
   132       ///The cost function is unbounded
 
   134       ///\todo Give a feasible solution and an infinite ray (and the
 
   135       ///corresponding bases)
 
   139     ///\e The type of the investigated LP problem
 
   141       ///Primal-dual feasible
 
   142       PRIMAL_DUAL_FEASIBLE = 0,
 
   143       ///Primal feasible dual infeasible
 
   144       PRIMAL_FEASIBLE_DUAL_INFEASIBLE = 1,
 
   145       ///Primal infeasible dual feasible
 
   146       PRIMAL_INFEASIBLE_DUAL_FEASIBLE = 2,
 
   147       ///Primal-dual infeasible
 
   148       PRIMAL_DUAL_INFEASIBLE = 3,
 
   149       ///Could not determine so far
 
   153     ///The floating point type used by the solver
 
   154     typedef double Value;
 
   155     ///The infinity constant
 
   156     static const Value INF;
 
   157     ///The not a number constant
 
   158     static const Value NaN;
 
   160     ///Refer to a column of the LP.
 
   162     ///This type is used to refer to a column of the LP.
 
   164     ///Its value remains valid and correct even after the addition or erase of
 
   167     ///\todo Document what can one do with a Col (INVALID, comparing,
 
   168     ///it is similar to Node/Edge)
 
   172       friend class LpSolverBase;
 
   174       typedef Value ExprValue;
 
   175       typedef True LpSolverCol;
 
   177       Col(const Invalid&) : id(-1) {}
 
   178       bool operator<(Col c) const  {return id<c.id;}
 
   179       bool operator==(Col c) const  {return id==c.id;}
 
   180       bool operator!=(Col c) const  {return id==c.id;}
 
   183     ///Refer to a row of the LP.
 
   185     ///This type is used to refer to a row of the LP.
 
   187     ///Its value remains valid and correct even after the addition or erase of
 
   190     ///\todo Document what can one do with a Row (INVALID, comparing,
 
   191     ///it is similar to Node/Edge)
 
   195       friend class LpSolverBase;
 
   197       typedef Value ExprValue;
 
   198       typedef True LpSolverRow;
 
   200       Row(const Invalid&) : id(-1) {}
 
   202       bool operator<(Row c) const  {return id<c.id;}
 
   203       bool operator==(Row c) const  {return id==c.id;}
 
   204       bool operator!=(Row c) const  {return id==c.id;} 
 
   207     ///Linear expression of variables and a constant component
 
   209     ///This data structure strores a linear expression of the variables
 
   210     ///(\ref Col "Col"s) and also has a constant component.
 
   212     ///There are several ways to access and modify the contents of this
 
   214     ///- Its it fully compatible with \c std::map<Col,double>, so for expamle
 
   215     ///if \c e is an Expr and \c v and \c w are of type \ref Col, then you can
 
   216     ///read and modify the coefficients like
 
   223     ///or you can also iterate through its elements.
 
   226     ///for(LpSolverBase::Expr::iterator i=e.begin();i!=e.end();++i)
 
   229     ///(This code computes the sum of all coefficients).
 
   230     ///- Numbers (<tt>double</tt>'s)
 
   231     ///and variables (\ref Col "Col"s) directly convert to an
 
   232     ///\ref Expr and the usual linear operations are defined so  
 
   235     ///2*v-3.12*(v-w/2)+2
 
   236     ///v*2.1+(3*v+(v*12+w+6)*3)/2
 
   238     ///are valid \ref Expr "Expr"essions.
 
   239     ///The usual assignment operations are also defined.
 
   242     ///e+=2*v-3.12*(v-w/2)+2;
 
   246     ///- The constant member can be set and read by \ref constComp()
 
   249     ///double c=e.constComp();
 
   252     ///\note \ref clear() not only sets all coefficients to 0 but also
 
   253     ///clears the constant components.
 
   257     class Expr : public std::map<Col,Value>
 
   260       typedef LpSolverBase::Col Key; 
 
   261       typedef LpSolverBase::Value Value;
 
   264       typedef std::map<Col,Value> Base;
 
   268       typedef True IsLinExpression;
 
   270       Expr() : Base(), const_comp(0) { }
 
   272       Expr(const Key &v) : const_comp(0) {
 
   273 	Base::insert(std::make_pair(v, 1));
 
   276       Expr(const Value &v) : const_comp(v) {}
 
   278       void set(const Key &v,const Value &c) {
 
   279 	Base::insert(std::make_pair(v, c));
 
   282       Value &constComp() { return const_comp; }
 
   284       const Value &constComp() const { return const_comp; }
 
   286       ///Removes the components with zero coefficient.
 
   288 	for (Base::iterator i=Base::begin(); i!=Base::end();) {
 
   291 	  if ((*i).second==0) Base::erase(i);
 
   296       ///Sets all coefficients and the constant component to 0.
 
   303       Expr &operator+=(const Expr &e) {
 
   304 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
 
   305 	  (*this)[j->first]+=j->second;
 
   306 	///\todo it might be speeded up using "hints"
 
   307 	const_comp+=e.const_comp;
 
   311       Expr &operator-=(const Expr &e) {
 
   312 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
 
   313 	  (*this)[j->first]-=j->second;
 
   314 	const_comp-=e.const_comp;
 
   318       Expr &operator*=(const Value &c) {
 
   319 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
 
   325       Expr &operator/=(const Value &c) {
 
   326 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
 
   335     ///This data stucture represents a linear constraint in the LP.
 
   336     ///Basically it is a linear expression with a lower or an upper bound
 
   337     ///(or both). These parts of the constraint can be obtained by the member
 
   338     ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
 
   340     ///There are two ways to construct a constraint.
 
   341     ///- You can set the linear expression and the bounds directly
 
   342     ///  by the functions above.
 
   343     ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
 
   344     ///  are defined between expressions, or even between constraints whenever
 
   345     ///  it makes sense. Therefore if \c e and \c f are linear expressions and
 
   346     ///  \c s and \c t are numbers, then the followings are valid expressions
 
   347     ///  and thus they can be used directly e.g. in \ref addRow() whenever
 
   355     ///\warning The validity of a constraint is checked only at run time, so
 
   356     ///e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will compile, but will throw a
 
   357     ///\ref LogicError exception.
 
   361       typedef LpSolverBase::Expr Expr;
 
   362       typedef Expr::Key Key;
 
   363       typedef Expr::Value Value;
 
   365 //       static const Value INF;
 
   366 //       static const Value NaN;
 
   373       Constr() : _expr(), _lb(NaN), _ub(NaN) {}
 
   375       Constr(Value lb,const Expr &e,Value ub) :
 
   376 	_expr(e), _lb(lb), _ub(ub) {}
 
   378       Constr(const Expr &e,Value ub) : 
 
   379 	_expr(e), _lb(NaN), _ub(ub) {}
 
   381       Constr(Value lb,const Expr &e) :
 
   382 	_expr(e), _lb(lb), _ub(NaN) {}
 
   384       Constr(const Expr &e) : 
 
   385 	_expr(e), _lb(NaN), _ub(NaN) {}
 
   393       ///Reference to the linear expression 
 
   394       Expr &expr() { return _expr; }
 
   395       ///Cont reference to the linear expression 
 
   396       const Expr &expr() const { return _expr; }
 
   397       ///Reference to the lower bound.
 
   400       ///- \ref INF "INF": the constraint is lower unbounded.
 
   401       ///- \ref NaN "NaN": lower bound has not been set.
 
   402       ///- finite number: the lower bound
 
   403       Value &lowerBound() { return _lb; }
 
   404       ///The const version of \ref lowerBound()
 
   405       const Value &lowerBound() const { return _lb; }
 
   406       ///Reference to the upper bound.
 
   409       ///- \ref INF "INF": the constraint is upper unbounded.
 
   410       ///- \ref NaN "NaN": upper bound has not been set.
 
   411       ///- finite number: the upper bound
 
   412       Value &upperBound() { return _ub; }
 
   413       ///The const version of \ref upperBound()
 
   414       const Value &upperBound() const { return _ub; }
 
   415       ///Is the constraint lower bounded?
 
   416       bool lowerBounded() const { 
 
   420       ///Is the constraint upper bounded?
 
   421       bool upperBounded() const {
 
   427     ///Linear expression of rows
 
   429     ///This data structure represents a column of the matrix,
 
   430     ///thas is it strores a linear expression of the dual variables
 
   431     ///(\ref Row "Row"s).
 
   433     ///There are several ways to access and modify the contents of this
 
   435     ///- Its it fully compatible with \c std::map<Row,double>, so for expamle
 
   436     ///if \c e is an DualExpr and \c v
 
   437     ///and \c w are of type \ref Row, then you can
 
   438     ///read and modify the coefficients like
 
   445     ///or you can also iterate through its elements.
 
   448     ///for(LpSolverBase::DualExpr::iterator i=e.begin();i!=e.end();++i)
 
   451     ///(This code computes the sum of all coefficients).
 
   452     ///- Numbers (<tt>double</tt>'s)
 
   453     ///and variables (\ref Row "Row"s) directly convert to an
 
   454     ///\ref DualExpr and the usual linear operations are defined so  
 
   458     ///v*2.1+(3*v+(v*12+w)*3)/2
 
   460     ///are valid \ref DualExpr "DualExpr"essions.
 
   461     ///The usual assignment operations are also defined.
 
   464     ///e+=2*v-3.12*(v-w/2);
 
   471     class DualExpr : public std::map<Row,Value>
 
   474       typedef LpSolverBase::Row Key; 
 
   475       typedef LpSolverBase::Value Value;
 
   478       typedef std::map<Row,Value> Base;
 
   481       typedef True IsLinExpression;
 
   483       DualExpr() : Base() { }
 
   485       DualExpr(const Key &v) {
 
   486 	Base::insert(std::make_pair(v, 1));
 
   489       void set(const Key &v,const Value &c) {
 
   490 	Base::insert(std::make_pair(v, c));
 
   493       ///Removes the components with zero coefficient.
 
   495 	for (Base::iterator i=Base::begin(); i!=Base::end();) {
 
   498 	  if ((*i).second==0) Base::erase(i);
 
   503       ///Sets all coefficients to 0.
 
   509       DualExpr &operator+=(const DualExpr &e) {
 
   510 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
 
   511 	  (*this)[j->first]+=j->second;
 
   512 	///\todo it might be speeded up using "hints"
 
   516       DualExpr &operator-=(const DualExpr &e) {
 
   517 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
 
   518 	  (*this)[j->first]-=j->second;
 
   522       DualExpr &operator*=(const Value &c) {
 
   523 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
 
   528       DualExpr &operator/=(const Value &c) {
 
   529 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
 
   540     //Abstract virtual functions
 
   541     virtual LpSolverBase &_newLp() = 0;
 
   542     virtual LpSolverBase &_copyLp(){
 
   543       ///\todo This should be implemented here, too,  when we have problem retrieving routines. It can be overriden.
 
   546       LpSolverBase & newlp(_newLp());
 
   548       //return *(LpSolverBase*)0;
 
   551     virtual int _addCol() = 0;
 
   552     virtual int _addRow() = 0;
 
   553     virtual void _eraseCol(int col) = 0;
 
   554     virtual void _eraseRow(int row) = 0;
 
   555     virtual void _setRowCoeffs(int i, 
 
   558                                Value  const * values ) = 0;
 
   559     virtual void _setColCoeffs(int i, 
 
   562                                Value  const * values ) = 0;
 
   563     virtual void _setCoeff(int row, int col, Value value) = 0;
 
   564     virtual void _setColLowerBound(int i, Value value) = 0;
 
   565     virtual void _setColUpperBound(int i, Value value) = 0;
 
   566 //     virtual void _setRowLowerBound(int i, Value value) = 0;
 
   567 //     virtual void _setRowUpperBound(int i, Value value) = 0;
 
   568     virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
 
   569     virtual void _setObjCoeff(int i, Value obj_coef) = 0;
 
   570     virtual void _clearObj()=0;
 
   571 //     virtual void _setObj(int length,
 
   572 //                          int  const * indices, 
 
   573 //                          Value  const * values ) = 0;
 
   574     virtual SolveExitStatus _solve() = 0;
 
   575     virtual Value _getPrimal(int i) = 0;
 
   576     virtual Value _getPrimalValue() = 0;
 
   577     virtual SolutionStatus _getPrimalStatus() = 0;
 
   578     virtual SolutionStatus _getDualStatus() = 0;
 
   579     ///\todo This could be implemented here, too, using _getPrimalStatus() and
 
   581     virtual ProblemTypes _getProblemType() = 0;
 
   583     virtual void _setMax() = 0;
 
   584     virtual void _setMin() = 0;
 
   586     //Own protected stuff
 
   588     //Constant component of the objective function
 
   589     Value obj_const_comp;
 
   597     LpSolverBase() : obj_const_comp(0) {}
 
   600     virtual ~LpSolverBase() {}
 
   602     ///Creates a new LP problem
 
   603     LpSolverBase &newLp() {return _newLp();}
 
   604     ///Makes a copy of the LP problem
 
   605     LpSolverBase ©Lp() {return _copyLp();}
 
   607     ///\name Build up and modify the LP
 
   611     ///Add a new empty column (i.e a new variable) to the LP
 
   612     Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;}
 
   614     ///\brief Adds several new columns
 
   615     ///(i.e a variables) at once
 
   617     ///This magic function takes a container as its argument
 
   618     ///and fills its elements
 
   619     ///with new columns (i.e. variables)
 
   621     ///- a standard STL compatible iterable container with
 
   622     ///\ref Col as its \c values_type
 
   625     ///std::vector<LpSolverBase::Col>
 
   626     ///std::list<LpSolverBase::Col>
 
   628     ///- a standard STL compatible iterable container with
 
   629     ///\ref Col as its \c mapped_type
 
   632     ///std::map<AnyType,LpSolverBase::Col>
 
   634     ///- an iterable lemon \ref concept::WriteMap "write map" like 
 
   636     ///ListGraph::NodeMap<LpSolverBase::Col>
 
   637     ///ListGraph::EdgeMap<LpSolverBase::Col>
 
   639     ///\return The number of the created column.
 
   642     int addColSet(T &t) { return 0;} 
 
   645     typename enable_if<typename T::value_type::LpSolverCol,int>::type
 
   646     addColSet(T &t,dummy<0> = 0) {
 
   648       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
 
   652     typename enable_if<typename T::value_type::second_type::LpSolverCol,
 
   654     addColSet(T &t,dummy<1> = 1) { 
 
   656       for(typename T::iterator i=t.begin();i!=t.end();++i) {
 
   663     typename enable_if<typename T::ValueSet::value_type::LpSolverCol,
 
   665     addColSet(T &t,dummy<2> = 2) { 
 
   666       ///\bug <tt>return addColSet(t.valueSet());</tt> should also work.
 
   668       for(typename T::ValueSet::iterator i=t.valueSet().begin();
 
   669 	  i!=t.valueSet().end();
 
   679     ///Set a column (i.e a dual constraint) of the LP
 
   681     ///\param c is the column to be modified
 
   682     ///\param e is a dual linear expression (see \ref DualExpr)
 
   683     ///\bug This is a temporary function. The interface will change to
 
   685     void setCol(Col c,const DualExpr &e) {
 
   686       std::vector<int> indices;
 
   687       std::vector<Value> values;
 
   688       indices.push_back(0);
 
   690       for(DualExpr::const_iterator i=e.begin(); i!=e.end(); ++i)
 
   691 	if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
 
   692 	  indices.push_back(cols.floatingId((*i).first.id));
 
   693 	  values.push_back((*i).second);
 
   695       _setColCoeffs(cols.floatingId(c.id),indices.size()-1,
 
   696 		    &indices[0],&values[0]);
 
   699     ///Add a new column to the LP
 
   701     ///\param e is a dual linear expression (see \ref DualExpr)
 
   702     ///\param obj is the corresponding component of the objective
 
   703     ///function. It is 0 by default.
 
   704     ///\return The created column.
 
   705     ///\bug This is a temportary function. The interface will change to
 
   707     Col addCol(const DualExpr &e, Value obj=0) {
 
   714     ///Add a new empty row (i.e a new constraint) to the LP
 
   716     ///This function adds a new empty row (i.e a new constraint) to the LP.
 
   717     ///\return The created row
 
   718     Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;}
 
   720     ///\brief Add several new rows
 
   721     ///(i.e a constraints) at once
 
   723     ///This magic function takes a container as its argument
 
   724     ///and fills its elements
 
   725     ///with new row (i.e. variables)
 
   727     ///- a standard STL compatible iterable container with
 
   728     ///\ref Row as its \c values_type
 
   731     ///std::vector<LpSolverBase::Row>
 
   732     ///std::list<LpSolverBase::Row>
 
   734     ///- a standard STL compatible iterable container with
 
   735     ///\ref Row as its \c mapped_type
 
   738     ///std::map<AnyType,LpSolverBase::Row>
 
   740     ///- an iterable lemon \ref concept::WriteMap "write map" like 
 
   742     ///ListGraph::NodeMap<LpSolverBase::Row>
 
   743     ///ListGraph::EdgeMap<LpSolverBase::Row>
 
   745     ///\return The number of rows created.
 
   748     int addRowSet(T &t) { return 0;} 
 
   751     typename enable_if<typename T::value_type::LpSolverRow,int>::type
 
   752     addRowSet(T &t,dummy<0> = 0) {
 
   754       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
 
   758     typename enable_if<typename T::value_type::second_type::LpSolverRow,
 
   760     addRowSet(T &t,dummy<1> = 1) { 
 
   762       for(typename T::iterator i=t.begin();i!=t.end();++i) {
 
   769     typename enable_if<typename T::ValueSet::value_type::LpSolverRow,
 
   771     addRowSet(T &t,dummy<2> = 2) { 
 
   772       ///\bug <tt>return addRowSet(t.valueSet());</tt> should also work.
 
   774       for(typename T::ValueSet::iterator i=t.valueSet().begin();
 
   775 	  i!=t.valueSet().end();
 
   785     ///Set a row (i.e a constraint) of the LP
 
   787     ///\param r is the row to be modified
 
   788     ///\param l is lower bound (-\ref INF means no bound)
 
   789     ///\param e is a linear expression (see \ref Expr)
 
   790     ///\param u is the upper bound (\ref INF means no bound)
 
   791     ///\bug This is a temportary function. The interface will change to
 
   793     ///\todo Option to control whether a constraint with a single variable is
 
   795     void setRow(Row r, Value l,const Expr &e, Value u) {
 
   796       std::vector<int> indices;
 
   797       std::vector<Value> values;
 
   798       indices.push_back(0);
 
   800       for(Expr::const_iterator i=e.begin(); i!=e.end(); ++i)
 
   801 	if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
 
   802 	  indices.push_back(cols.floatingId((*i).first.id));
 
   803 	  values.push_back((*i).second);
 
   805       _setRowCoeffs(rows.floatingId(r.id),indices.size()-1,
 
   806 		    &indices[0],&values[0]);
 
   807 //       _setRowLowerBound(rows.floatingId(r.id),l-e.constComp());
 
   808 //       _setRowUpperBound(rows.floatingId(r.id),u-e.constComp());
 
   809        _setRowBounds(rows.floatingId(r.id),l-e.constComp(),u-e.constComp());
 
   812     ///Set a row (i.e a constraint) of the LP
 
   814     ///\param r is the row to be modified
 
   815     ///\param c is a linear expression (see \ref Constr)
 
   816     void setRow(Row r, const Constr &c) {
 
   818 	     c.lowerBounded()?c.lowerBound():-INF,
 
   820 	     c.upperBounded()?c.upperBound():INF);
 
   823     ///Add a new row (i.e a new constraint) to the LP
 
   825     ///\param l is the lower bound (-\ref INF means no bound)
 
   826     ///\param e is a linear expression (see \ref Expr)
 
   827     ///\param u is the upper bound (\ref INF means no bound)
 
   828     ///\return The created row.
 
   829     ///\bug This is a temportary function. The interface will change to
 
   831     Row addRow(Value l,const Expr &e, Value u) {
 
   837     ///Add a new row (i.e a new constraint) to the LP
 
   839     ///\param c is a linear expression (see \ref Constr)
 
   840     ///\return The created row.
 
   841     Row addRow(const Constr &c) {
 
   846     ///Erase a coloumn (i.e a variable) from the LP
 
   848     ///\param c is the coloumn to be deleted
 
   849     ///\todo Please check this
 
   850     void eraseCol(Col c) {
 
   851       _eraseCol(cols.floatingId(c.id));
 
   854     ///Erase a  row (i.e a constraint) from the LP
 
   856     ///\param r is the row to be deleted
 
   857     ///\todo Please check this
 
   858     void eraseRow(Row r) {
 
   859       _eraseRow(rows.floatingId(r.id));
 
   863     ///Set an element of the coefficient matrix of the LP
 
   865     ///\param r is the row of the element to be modified
 
   866     ///\param c is the coloumn of the element to be modified
 
   867     ///\param val is the new value of the coefficient
 
   868     void setCoeff(Row r, Col c, Value val){
 
   869       _setCoeff(rows.floatingId(r.id),cols.floatingId(c.id), val);
 
   872     /// Set the lower bound of a column (i.e a variable)
 
   874     /// The upper bound of a variable (column) has to be given by an 
 
   875     /// extended number of type Value, i.e. a finite number of type 
 
   876     /// Value or -\ref INF.
 
   877     void colLowerBound(Col c, Value value) {
 
   878       _setColLowerBound(cols.floatingId(c.id),value);
 
   880     /// Set the upper bound of a column (i.e a variable)
 
   882     /// The upper bound of a variable (column) has to be given by an 
 
   883     /// extended number of type Value, i.e. a finite number of type 
 
   884     /// Value or \ref INF.
 
   885     void colUpperBound(Col c, Value value) {
 
   886       _setColUpperBound(cols.floatingId(c.id),value);
 
   888     /// Set the lower and the upper bounds of a column (i.e a variable)
 
   890     /// The lower and the upper bounds of
 
   891     /// a variable (column) have to be given by an 
 
   892     /// extended number of type Value, i.e. a finite number of type 
 
   893     /// Value, -\ref INF or \ref INF.
 
   894     void colBounds(Col c, Value lower, Value upper) {
 
   895       _setColLowerBound(cols.floatingId(c.id),lower);
 
   896       _setColUpperBound(cols.floatingId(c.id),upper);
 
   899 //     /// Set the lower bound of a row (i.e a constraint)
 
   901 //     /// The lower bound of a linear expression (row) has to be given by an 
 
   902 //     /// extended number of type Value, i.e. a finite number of type 
 
   903 //     /// Value or -\ref INF.
 
   904 //     void rowLowerBound(Row r, Value value) {
 
   905 //       _setRowLowerBound(rows.floatingId(r.id),value);
 
   907 //     /// Set the upper bound of a row (i.e a constraint)
 
   909 //     /// The upper bound of a linear expression (row) has to be given by an 
 
   910 //     /// extended number of type Value, i.e. a finite number of type 
 
   911 //     /// Value or \ref INF.
 
   912 //     void rowUpperBound(Row r, Value value) {
 
   913 //       _setRowUpperBound(rows.floatingId(r.id),value);
 
   916     /// Set the lower and the upper bounds of a row (i.e a constraint)
 
   918     /// The lower and the upper bounds of
 
   919     /// a constraint (row) have to be given by an 
 
   920     /// extended number of type Value, i.e. a finite number of type 
 
   921     /// Value, -\ref INF or \ref INF.
 
   922     void rowBounds(Row c, Value lower, Value upper) {
 
   923       _setRowBounds(rows.floatingId(c.id),lower, upper);
 
   924       // _setRowUpperBound(rows.floatingId(c.id),upper);
 
   927     ///Set an element of the objective function
 
   928     void objCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); };
 
   929     ///Set the objective function
 
   931     ///\param e is a linear expression of type \ref Expr.
 
   932     ///\bug The previous objective function is not cleared!
 
   933     void setObj(Expr e) {
 
   935       for (Expr::iterator i=e.begin(); i!=e.end(); ++i)
 
   936 	objCoeff((*i).first,(*i).second);
 
   937       obj_const_comp=e.constComp();
 
   941     void max() { _setMax(); }
 
   943     void min() { _setMin(); }
 
   949     ///\name Solve the LP
 
   953     ///\e Solve the LP problem at hand
 
   955     ///\return The result of the optimization procedure. Possible values and their meanings can be found in the documentation of \ref SolveExitStatus.
 
   957     ///\todo Which method is used to solve the problem
 
   958     SolveExitStatus solve() { return _solve(); }
 
   962     ///\name Obtain the solution
 
   966     /// The status of the primal problem (the original LP problem)
 
   967     SolutionStatus primalStatus() {
 
   968       return _getPrimalStatus();
 
   971     /// The status of the dual (of the original LP) problem 
 
   972     SolutionStatus dualStatus() {
 
   973       return _getDualStatus();
 
   976     ///The type of the original LP problem
 
   977     ProblemTypes problemType() {
 
   978       return _getProblemType();
 
   982     Value primal(Col c) { return _getPrimal(cols.floatingId(c.id)); }
 
   987     ///- \ref INF or -\ref INF means either infeasibility or unboundedness
 
   988     /// of the primal problem, depending on whether we minimize or maximize.
 
   989     ///- \ref NaN if no primal solution is found.
 
   990     ///- The (finite) objective value if an optimal solution is found.
 
   991     Value primalValue() { return _getPrimalValue()+obj_const_comp;}
 
   998   ///\relates LpSolverBase::Expr
 
  1000   inline LpSolverBase::Expr operator+(const LpSolverBase::Expr &a,
 
  1001 				      const LpSolverBase::Expr &b) 
 
  1003     LpSolverBase::Expr tmp(a);
 
  1004     tmp+=b; ///\todo Doesn't STL have some special 'merge' algorithm?
 
  1009   ///\relates LpSolverBase::Expr
 
  1011   inline LpSolverBase::Expr operator-(const LpSolverBase::Expr &a,
 
  1012 				      const LpSolverBase::Expr &b) 
 
  1014     LpSolverBase::Expr tmp(a);
 
  1015     tmp-=b; ///\todo Doesn't STL have some special 'merge' algorithm?
 
  1020   ///\relates LpSolverBase::Expr
 
  1022   inline LpSolverBase::Expr operator*(const LpSolverBase::Expr &a,
 
  1023 				      const LpSolverBase::Value &b) 
 
  1025     LpSolverBase::Expr tmp(a);
 
  1026     tmp*=b; ///\todo Doesn't STL have some special 'merge' algorithm?
 
  1032   ///\relates LpSolverBase::Expr
 
  1034   inline LpSolverBase::Expr operator*(const LpSolverBase::Value &a,
 
  1035 				      const LpSolverBase::Expr &b) 
 
  1037     LpSolverBase::Expr tmp(b);
 
  1038     tmp*=a; ///\todo Doesn't STL have some special 'merge' algorithm?
 
  1043   ///\relates LpSolverBase::Expr
 
  1045   inline LpSolverBase::Expr operator/(const LpSolverBase::Expr &a,
 
  1046 				      const LpSolverBase::Value &b) 
 
  1048     LpSolverBase::Expr tmp(a);
 
  1049     tmp/=b; ///\todo Doesn't STL have some special 'merge' algorithm?
 
  1055   ///\relates LpSolverBase::Constr
 
  1057   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
 
  1058 					 const LpSolverBase::Expr &f) 
 
  1060     return LpSolverBase::Constr(-LpSolverBase::INF,e-f,0);
 
  1065   ///\relates LpSolverBase::Constr
 
  1067   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &e,
 
  1068 					 const LpSolverBase::Expr &f) 
 
  1070     return LpSolverBase::Constr(e,f);
 
  1075   ///\relates LpSolverBase::Constr
 
  1077   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
 
  1078 					 const LpSolverBase::Value &f) 
 
  1080     return LpSolverBase::Constr(e,f);
 
  1085   ///\relates LpSolverBase::Constr
 
  1087   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
 
  1088 					 const LpSolverBase::Expr &f) 
 
  1090     return LpSolverBase::Constr(-LpSolverBase::INF,f-e,0);
 
  1096   ///\relates LpSolverBase::Constr
 
  1098   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &e,
 
  1099 					 const LpSolverBase::Expr &f) 
 
  1101     return LpSolverBase::Constr(f,e);
 
  1107   ///\relates LpSolverBase::Constr
 
  1109   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
 
  1110 					 const LpSolverBase::Value &f) 
 
  1112     return LpSolverBase::Constr(f,e);
 
  1117   ///\relates LpSolverBase::Constr
 
  1119   inline LpSolverBase::Constr operator==(const LpSolverBase::Expr &e,
 
  1120 					 const LpSolverBase::Expr &f) 
 
  1122     return LpSolverBase::Constr(0,e-f,0);
 
  1127   ///\relates LpSolverBase::Constr
 
  1129   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &n,
 
  1130 					 const LpSolverBase::Constr&c) 
 
  1132     LpSolverBase::Constr tmp(c);
 
  1133     ///\todo Create an own exception type.
 
  1134     if(!isnan(tmp.lowerBound())) throw LogicError();
 
  1135     else tmp.lowerBound()=n;
 
  1140   ///\relates LpSolverBase::Constr
 
  1142   inline LpSolverBase::Constr operator<=(const LpSolverBase::Constr& c,
 
  1143 					 const LpSolverBase::Value &n)
 
  1145     LpSolverBase::Constr tmp(c);
 
  1146     ///\todo Create an own exception type.
 
  1147     if(!isnan(tmp.upperBound())) throw LogicError();
 
  1148     else tmp.upperBound()=n;
 
  1154   ///\relates LpSolverBase::Constr
 
  1156   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &n,
 
  1157 					 const LpSolverBase::Constr&c) 
 
  1159     LpSolverBase::Constr tmp(c);
 
  1160     ///\todo Create an own exception type.
 
  1161     if(!isnan(tmp.upperBound())) throw LogicError();
 
  1162     else tmp.upperBound()=n;
 
  1167   ///\relates LpSolverBase::Constr
 
  1169   inline LpSolverBase::Constr operator>=(const LpSolverBase::Constr& c,
 
  1170 					 const LpSolverBase::Value &n)
 
  1172     LpSolverBase::Constr tmp(c);
 
  1173     ///\todo Create an own exception type.
 
  1174     if(!isnan(tmp.lowerBound())) throw LogicError();
 
  1175     else tmp.lowerBound()=n;
 
  1181   ///\relates LpSolverBase::DualExpr
 
  1183   inline LpSolverBase::DualExpr operator+(const LpSolverBase::DualExpr &a,
 
  1184 				      const LpSolverBase::DualExpr &b) 
 
  1186     LpSolverBase::DualExpr tmp(a);
 
  1187     tmp+=b; ///\todo Doesn't STL have some special 'merge' algorithm?
 
  1192   ///\relates LpSolverBase::DualExpr
 
  1194   inline LpSolverBase::DualExpr operator-(const LpSolverBase::DualExpr &a,
 
  1195 				      const LpSolverBase::DualExpr &b) 
 
  1197     LpSolverBase::DualExpr tmp(a);
 
  1198     tmp-=b; ///\todo Doesn't STL have some special 'merge' algorithm?
 
  1203   ///\relates LpSolverBase::DualExpr
 
  1205   inline LpSolverBase::DualExpr operator*(const LpSolverBase::DualExpr &a,
 
  1206 				      const LpSolverBase::Value &b) 
 
  1208     LpSolverBase::DualExpr tmp(a);
 
  1209     tmp*=b; ///\todo Doesn't STL have some special 'merge' algorithm?
 
  1215   ///\relates LpSolverBase::DualExpr
 
  1217   inline LpSolverBase::DualExpr operator*(const LpSolverBase::Value &a,
 
  1218 				      const LpSolverBase::DualExpr &b) 
 
  1220     LpSolverBase::DualExpr tmp(b);
 
  1221     tmp*=a; ///\todo Doesn't STL have some special 'merge' algorithm?
 
  1226   ///\relates LpSolverBase::DualExpr
 
  1228   inline LpSolverBase::DualExpr operator/(const LpSolverBase::DualExpr &a,
 
  1229 				      const LpSolverBase::Value &b) 
 
  1231     LpSolverBase::DualExpr tmp(a);
 
  1232     tmp/=b; ///\todo Doesn't STL have some special 'merge' algorithm?
 
  1239 #endif //LEMON_LP_BASE_H