src/lemon/lp_base.h
changeset 1435 8e85e6bbefdf
parent 1405 3626c7f10f14
equal deleted inserted replaced
12:d933e7bad633 -1:000000000000
     1 /* -*- C++ -*-
       
     2  * src/lemon/lp_base.h - Part of LEMON, a generic C++ optimization library
       
     3  *
       
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
       
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
       
     6  *
       
     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.
       
    10  *
       
    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
       
    13  * purpose.
       
    14  *
       
    15  */
       
    16 
       
    17 #ifndef LEMON_LP_BASE_H
       
    18 #define LEMON_LP_BASE_H
       
    19 
       
    20 #include<vector>
       
    21 #include<map>
       
    22 #include<limits>
       
    23 #include<cmath>
       
    24 
       
    25 #include<lemon/utility.h>
       
    26 #include<lemon/error.h>
       
    27 #include<lemon/invalid.h>
       
    28 
       
    29 //#include"lin_expr.h"
       
    30 
       
    31 ///\file
       
    32 ///\brief The interface of the LP solver interface.
       
    33 ///\ingroup gen_opt_group
       
    34 namespace lemon {
       
    35   
       
    36   ///Internal data structure to convert floating id's to fix one's
       
    37     
       
    38   ///\todo This might be implemented to be also usable in other places.
       
    39   class _FixId 
       
    40   {
       
    41     std::vector<int> index;
       
    42     std::vector<int> cross;
       
    43     int first_free;
       
    44   public:
       
    45     _FixId() : first_free(-1) {};
       
    46     ///Convert a floating id to a fix one
       
    47 
       
    48     ///\param n is a floating id
       
    49     ///\return the corresponding fix id
       
    50     int fixId(int n) {return cross[n];}
       
    51     ///Convert a fix id to a floating one
       
    52 
       
    53     ///\param n is a fix id
       
    54     ///\return the corresponding floating id
       
    55     int floatingId(int n) { return index[n];}
       
    56     ///Add a new floating id.
       
    57 
       
    58     ///\param n is a floating id
       
    59     ///\return the fix id of the new value
       
    60     ///\todo Multiple additions should also be handled.
       
    61     int insert(int n)
       
    62     {
       
    63       if(n>=int(cross.size())) {
       
    64 	cross.resize(n+1);
       
    65 	if(first_free==-1) {
       
    66 	  cross[n]=index.size();
       
    67 	  index.push_back(n);
       
    68 	}
       
    69 	else {
       
    70 	  cross[n]=first_free;
       
    71 	  int next=index[first_free];
       
    72 	  index[first_free]=n;
       
    73 	  first_free=next;
       
    74 	}
       
    75 	return cross[n];
       
    76       }
       
    77       ///\todo Create an own exception type.
       
    78       else throw LogicError(); //floatingId-s must form a continuous range;
       
    79     }
       
    80     ///Remove a fix id.
       
    81 
       
    82     ///\param n is a fix id
       
    83     ///
       
    84     void erase(int n) 
       
    85     {
       
    86       int fl=index[n];
       
    87       index[n]=first_free;
       
    88       first_free=n;
       
    89       for(int i=fl+1;i<int(cross.size());++i) {
       
    90 	cross[i-1]=cross[i];
       
    91 	index[cross[i]]--;
       
    92       }
       
    93       cross.pop_back();
       
    94     }
       
    95     ///An upper bound on the largest fix id.
       
    96 
       
    97     ///\todo Do we need this?
       
    98     ///
       
    99     std::size_t maxFixId() { return cross.size()-1; }
       
   100   
       
   101   };
       
   102     
       
   103   ///Common base class for LP solvers
       
   104   
       
   105   ///\todo Much more docs
       
   106   ///\ingroup gen_opt_group
       
   107   class LpSolverBase {
       
   108 
       
   109   public:
       
   110 
       
   111     ///\e
       
   112     enum SolveExitStatus {
       
   113       ///\e
       
   114       SOLVED = 0,
       
   115       ///\e
       
   116       UNSOLVED = 1
       
   117     };
       
   118       
       
   119     ///\e
       
   120     enum SolutionStatus {
       
   121       ///Feasible solution has'n been found (but may exist).
       
   122 
       
   123       ///\todo NOTFOUND might be a better name.
       
   124       ///
       
   125       UNDEFINED = 0,
       
   126       ///The problem has no feasible solution
       
   127       INFEASIBLE = 1,
       
   128       ///Feasible solution found
       
   129       FEASIBLE = 2,
       
   130       ///Optimal solution exists and found
       
   131       OPTIMAL = 3,
       
   132       ///The cost function is unbounded
       
   133 
       
   134       ///\todo Give a feasible solution and an infinite ray (and the
       
   135       ///corresponding bases)
       
   136       INFINITE = 4
       
   137     };
       
   138       
       
   139     ///The floating point type used by the solver
       
   140     typedef double Value;
       
   141     ///The infinity constant
       
   142     static const Value INF;
       
   143     ///The not a number constant
       
   144     static const Value NaN;
       
   145     
       
   146     ///Refer to a column of the LP.
       
   147 
       
   148     ///This type is used to refer to a column of the LP.
       
   149     ///
       
   150     ///Its value remains valid and correct even after the addition or erase of
       
   151     ///other columns.
       
   152     ///
       
   153     ///\todo Document what can one do with a Col (INVALID, comparing,
       
   154     ///it is similar to Node/Edge)
       
   155     class Col {
       
   156     protected:
       
   157       int id;
       
   158       friend class LpSolverBase;
       
   159     public:
       
   160       typedef Value ExprValue;
       
   161       typedef True LpSolverCol;
       
   162       Col() {}
       
   163       Col(const Invalid&) : id(-1) {}
       
   164       bool operator<(Col c) const  {return id<c.id;}
       
   165       bool operator==(Col c) const  {return id==c.id;}
       
   166       bool operator!=(Col c) const  {return id==c.id;}
       
   167     };
       
   168 
       
   169     ///Refer to a row of the LP.
       
   170 
       
   171     ///This type is used to refer to a row of the LP.
       
   172     ///
       
   173     ///Its value remains valid and correct even after the addition or erase of
       
   174     ///other rows.
       
   175     ///
       
   176     ///\todo Document what can one do with a Row (INVALID, comparing,
       
   177     ///it is similar to Node/Edge)
       
   178     class Row {
       
   179     protected:
       
   180       int id;
       
   181       friend class LpSolverBase;
       
   182     public:
       
   183       typedef Value ExprValue;
       
   184       typedef True LpSolverRow;
       
   185       Row() {}
       
   186       Row(const Invalid&) : id(-1) {}
       
   187       typedef True LpSolverRow;
       
   188       bool operator<(Row c) const  {return id<c.id;}
       
   189       bool operator==(Row c) const  {return id==c.id;}
       
   190       bool operator!=(Row c) const  {return id==c.id;} 
       
   191    };
       
   192     
       
   193     ///Linear expression of variables and a constant component
       
   194     
       
   195     ///This data structure strores a linear expression of the variables
       
   196     ///(\ref Col "Col"s) and also has a constant component.
       
   197     ///
       
   198     ///There are several ways to access and modify the contents of this
       
   199     ///container.
       
   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
       
   202     ///read and modify the coefficients like
       
   203     ///these.
       
   204     ///\code
       
   205     ///e[v]=5;
       
   206     ///e[v]+=12;
       
   207     ///e.erase(v);
       
   208     ///\endcode
       
   209     ///or you can also iterate through its elements.
       
   210     ///\code
       
   211     ///double s=0;
       
   212     ///for(LpSolverBase::Expr::iterator i=e.begin();i!=e.end();++i)
       
   213     ///  s+=i->second;
       
   214     ///\endcode
       
   215     ///(This code computes the sum of all coefficients).
       
   216     ///- Numbers (<tt>double</tt>'s)
       
   217     ///and variables (\ref Col "Col"s) directly convert to an
       
   218     ///\ref Expr and the usual linear operations are defined so  
       
   219     ///\code
       
   220     ///v+w
       
   221     ///2*v-3.12*(v-w/2)+2
       
   222     ///v*2.1+(3*v+(v*12+w+6)*3)/2
       
   223     ///\endcode
       
   224     ///are valid \ref Expr "Expr"essions.
       
   225     ///The usual assignment operations are also defined.
       
   226     ///\code
       
   227     ///e=v+w;
       
   228     ///e+=2*v-3.12*(v-w/2)+2;
       
   229     ///e*=3.4;
       
   230     ///e/=5;
       
   231     ///\endcode
       
   232     ///- The constant member can be set and read by \ref constComp()
       
   233     ///\code
       
   234     ///e.constComp()=12;
       
   235     ///double c=e.constComp();
       
   236     ///\endcode
       
   237     ///
       
   238     ///\note \ref clear() not only sets all coefficients to 0 but also
       
   239     ///clears the constant components.
       
   240     ///
       
   241     ///\sa Constr
       
   242     ///
       
   243     class Expr : public std::map<Col,Value>
       
   244     {
       
   245     public:
       
   246       typedef LpSolverBase::Col Key; 
       
   247       typedef LpSolverBase::Value Value;
       
   248       
       
   249     protected:
       
   250       typedef std::map<Col,Value> Base;
       
   251       
       
   252       Value const_comp;
       
   253   public:
       
   254       typedef True IsLinExpression;
       
   255       ///\e
       
   256       Expr() : Base(), const_comp(0) { }
       
   257       ///\e
       
   258       Expr(const Key &v) : const_comp(0) {
       
   259 	Base::insert(std::make_pair(v, 1));
       
   260       }
       
   261       ///\e
       
   262       Expr(const Value &v) : const_comp(v) {}
       
   263       ///\e
       
   264       void set(const Key &v,const Value &c) {
       
   265 	Base::insert(std::make_pair(v, c));
       
   266       }
       
   267       ///\e
       
   268       Value &constComp() { return const_comp; }
       
   269       ///\e
       
   270       const Value &constComp() const { return const_comp; }
       
   271       
       
   272       ///Removes the components with zero coefficient.
       
   273       void simplify() {
       
   274 	for (Base::iterator i=Base::begin(); i!=Base::end();) {
       
   275 	  Base::iterator j=i;
       
   276 	  ++j;
       
   277 	  if ((*i).second==0) Base::erase(i);
       
   278 	  j=i;
       
   279 	}
       
   280       }
       
   281 
       
   282       ///Sets all coefficients and the constant component to 0.
       
   283       void clear() {
       
   284 	Base::clear();
       
   285 	const_comp=0;
       
   286       }
       
   287 
       
   288       ///\e
       
   289       Expr &operator+=(const Expr &e) {
       
   290 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
       
   291 	  (*this)[j->first]+=j->second;
       
   292 	///\todo it might be speeded up using "hints"
       
   293 	const_comp+=e.const_comp;
       
   294 	return *this;
       
   295       }
       
   296       ///\e
       
   297       Expr &operator-=(const Expr &e) {
       
   298 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
       
   299 	  (*this)[j->first]-=j->second;
       
   300 	const_comp-=e.const_comp;
       
   301 	return *this;
       
   302       }
       
   303       ///\e
       
   304       Expr &operator*=(const Value &c) {
       
   305 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
       
   306 	  j->second*=c;
       
   307 	const_comp*=c;
       
   308 	return *this;
       
   309       }
       
   310       ///\e
       
   311       Expr &operator/=(const Value &c) {
       
   312 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
       
   313 	  j->second/=c;
       
   314 	const_comp/=c;
       
   315 	return *this;
       
   316       }
       
   317     };
       
   318     
       
   319     ///Linear constraint
       
   320 
       
   321     ///This data stucture represents a linear constraint in the LP.
       
   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.
       
   344     class Constr
       
   345     {
       
   346     public:
       
   347       typedef LpSolverBase::Expr Expr;
       
   348       typedef Expr::Key Key;
       
   349       typedef Expr::Value Value;
       
   350       
       
   351 //       static const Value INF;
       
   352 //       static const Value NaN;
       
   353 
       
   354     protected:
       
   355       Expr _expr;
       
   356       Value _lb,_ub;
       
   357     public:
       
   358       ///\e
       
   359       Constr() : _expr(), _lb(NaN), _ub(NaN) {}
       
   360       ///\e
       
   361       Constr(Value lb,const Expr &e,Value ub) :
       
   362 	_expr(e), _lb(lb), _ub(ub) {}
       
   363       ///\e
       
   364       Constr(const Expr &e,Value ub) : 
       
   365 	_expr(e), _lb(NaN), _ub(ub) {}
       
   366       ///\e
       
   367       Constr(Value lb,const Expr &e) :
       
   368 	_expr(e), _lb(lb), _ub(NaN) {}
       
   369       ///\e
       
   370       Constr(const Expr &e) : 
       
   371 	_expr(e), _lb(NaN), _ub(NaN) {}
       
   372       ///\e
       
   373       void clear() 
       
   374       {
       
   375 	_expr.clear();
       
   376 	_lb=_ub=NaN;
       
   377       }
       
   378 
       
   379       ///Reference to the linear expression 
       
   380       Expr &expr() { return _expr; }
       
   381       ///Cont reference to the linear expression 
       
   382       const Expr &expr() const { return _expr; }
       
   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
       
   389       Value &lowerBound() { return _lb; }
       
   390       ///The const version of \ref lowerBound()
       
   391       const Value &lowerBound() const { return _lb; }
       
   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
       
   398       Value &upperBound() { return _ub; }
       
   399       ///The const version of \ref upperBound()
       
   400       const Value &upperBound() const { return _ub; }
       
   401       ///Is the constraint lower bounded?
       
   402       bool lowerBounded() const { 
       
   403 	using namespace std;
       
   404 	return finite(_lb);
       
   405       }
       
   406       ///Is the constraint upper bounded?
       
   407       bool upperBounded() const {
       
   408 	using namespace std;
       
   409 	return finite(_ub);
       
   410       }
       
   411     };
       
   412     
       
   413 
       
   414   protected:
       
   415     _FixId rows;
       
   416     _FixId cols;
       
   417 
       
   418     //Abstract virtual functions
       
   419     virtual LpSolverBase &_newLp() = 0;
       
   420     virtual LpSolverBase &_copyLp() = 0;
       
   421 
       
   422     virtual int _addCol() = 0;
       
   423     virtual int _addRow() = 0;
       
   424     virtual void _setRowCoeffs(int i, 
       
   425 			       int length,
       
   426                                int  const * indices, 
       
   427                                Value  const * values ) = 0;
       
   428     virtual void _setColCoeffs(int i, 
       
   429 			       int length,
       
   430                                int  const * indices, 
       
   431                                Value  const * values ) = 0;
       
   432     virtual void _setCoeff(int row, int col, Value value) = 0;
       
   433     virtual void _setColLowerBound(int i, Value value) = 0;
       
   434     virtual void _setColUpperBound(int i, Value value) = 0;
       
   435 //     virtual void _setRowLowerBound(int i, Value value) = 0;
       
   436 //     virtual void _setRowUpperBound(int i, Value value) = 0;
       
   437     virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
       
   438     virtual void _setObjCoeff(int i, Value obj_coef) = 0;
       
   439     virtual void _clearObj()=0;
       
   440 //     virtual void _setObj(int length,
       
   441 //                          int  const * indices, 
       
   442 //                          Value  const * values ) = 0;
       
   443     virtual SolveExitStatus _solve() = 0;
       
   444     virtual Value _getPrimal(int i) = 0;
       
   445     virtual Value _getPrimalValue() = 0;
       
   446     virtual SolutionStatus _getPrimalStatus() = 0;
       
   447     virtual void _setMax() = 0;
       
   448     virtual void _setMin() = 0;
       
   449     
       
   450     //Own protected stuff
       
   451     
       
   452     //Constant component of the objective function
       
   453     Value obj_const_comp;
       
   454     
       
   455 
       
   456 
       
   457     
       
   458   public:
       
   459 
       
   460     ///\e
       
   461     LpSolverBase() : obj_const_comp(0) {}
       
   462 
       
   463     ///\e
       
   464     virtual ~LpSolverBase() {}
       
   465 
       
   466     ///Creates a new LP problem
       
   467     LpSolverBase &newLp() {return _newLp();}
       
   468     ///Makes a copy of the LP problem
       
   469     LpSolverBase &copyLp() {return _copyLp();}
       
   470     
       
   471     ///\name Build up and modify of the LP
       
   472 
       
   473     ///@{
       
   474 
       
   475     ///Add a new empty column (i.e a new variable) to the LP
       
   476     Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;}
       
   477 
       
   478     ///\brief Adds several new columns
       
   479     ///(i.e a variables) at once
       
   480     ///
       
   481     ///This magic function takes a container as its argument
       
   482     ///and fills its elements
       
   483     ///with new columns (i.e. variables)
       
   484     ///\param t can be
       
   485     ///- a standard STL compatible iterable container with
       
   486     ///\ref Col as its \c values_type
       
   487     ///like
       
   488     ///\code
       
   489     ///std::vector<LpSolverBase::Col>
       
   490     ///std::list<LpSolverBase::Col>
       
   491     ///\endcode
       
   492     ///- a standard STL compatible iterable container with
       
   493     ///\ref Col as its \c mapped_type
       
   494     ///like
       
   495     ///\code
       
   496     ///std::map<AnyType,LpSolverBase::Col>
       
   497     ///\endcode
       
   498     ///- an iterable lemon \ref concept::WriteMap "write map" like 
       
   499     ///\code
       
   500     ///ListGraph::NodeMap<LpSolverBase::Col>
       
   501     ///ListGraph::EdgeMap<LpSolverBase::Col>
       
   502     ///\endcode
       
   503     ///\return The number of the created column.
       
   504 #ifdef DOXYGEN
       
   505     template<class T>
       
   506     int addColSet(T &t) { return 0;} 
       
   507 #else
       
   508     template<class T>
       
   509     typename enable_if<typename T::value_type::LpSolverCol,int>::type
       
   510     addColSet(T &t,dummy<0> = 0) {
       
   511       int s=0;
       
   512       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
       
   513       return s;
       
   514     }
       
   515     template<class T>
       
   516     typename enable_if<typename T::value_type::second_type::LpSolverCol,
       
   517 		       int>::type
       
   518     addColSet(T &t,dummy<1> = 1) { 
       
   519       int s=0;
       
   520       for(typename T::iterator i=t.begin();i!=t.end();++i) {
       
   521 	i->second=addCol();
       
   522 	s++;
       
   523       }
       
   524       return s;
       
   525     }
       
   526     template<class T>
       
   527     typename enable_if<typename T::ValueSet::value_type::LpSolverCol,
       
   528 		       int>::type
       
   529     addColSet(T &t,dummy<2> = 2) { 
       
   530       ///\bug <tt>return addColSet(t.valueSet());</tt> should also work.
       
   531       int s=0;
       
   532       for(typename T::ValueSet::iterator i=t.valueSet().begin();
       
   533 	  i!=t.valueSet().end();
       
   534 	  ++i)
       
   535 	{
       
   536 	  *i=addCol();
       
   537 	  s++;
       
   538 	}
       
   539       return s;
       
   540     }
       
   541 #endif
       
   542 
       
   543     ///Add a new empty row (i.e a new constaint) to the LP
       
   544 
       
   545     ///This function adds a new empty row (i.e a new constaint) to the LP.
       
   546     ///\return The created row
       
   547     Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;}
       
   548 
       
   549     ///Set a row (i.e a constaint) of the LP
       
   550 
       
   551     ///\param r is the row to be modified
       
   552     ///\param l is lower bound (-\ref INF means no bound)
       
   553     ///\param e is a linear expression (see \ref Expr)
       
   554     ///\param u is the upper bound (\ref INF means no bound)
       
   555     ///\bug This is a temportary function. The interface will change to
       
   556     ///a better one.
       
   557     ///\todo Option to control whether a constraint with a single variable is
       
   558     ///added or not.
       
   559     void setRow(Row r, Value l,const Expr &e, Value u) {
       
   560       std::vector<int> indices;
       
   561       std::vector<Value> values;
       
   562       indices.push_back(0);
       
   563       values.push_back(0);
       
   564       for(Expr::const_iterator i=e.begin(); i!=e.end(); ++i)
       
   565 	if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
       
   566 	  indices.push_back(cols.floatingId((*i).first.id));
       
   567 	  values.push_back((*i).second);
       
   568 	}
       
   569       _setRowCoeffs(rows.floatingId(r.id),indices.size()-1,
       
   570 		    &indices[0],&values[0]);
       
   571 //       _setRowLowerBound(rows.floatingId(r.id),l-e.constComp());
       
   572 //       _setRowUpperBound(rows.floatingId(r.id),u-e.constComp());
       
   573        _setRowBounds(rows.floatingId(r.id),l-e.constComp(),u-e.constComp());
       
   574     }
       
   575 
       
   576     ///Set a row (i.e a constaint) of the LP
       
   577 
       
   578     ///\param r is the row to be modified
       
   579     ///\param c is a linear expression (see \ref Constr)
       
   580     void setRow(Row r, const Constr &c) {
       
   581       setRow(r,
       
   582 	     c.lowerBounded()?c.lowerBound():-INF,
       
   583 	     c.expr(),
       
   584 	     c.upperBounded()?c.upperBound():INF);
       
   585     }
       
   586 
       
   587     ///Add a new row (i.e a new constaint) to the LP
       
   588 
       
   589     ///\param l is the lower bound (-\ref INF means no bound)
       
   590     ///\param e is a linear expression (see \ref Expr)
       
   591     ///\param u is the upper bound (\ref INF means no bound)
       
   592     ///\return The created row.
       
   593     ///\bug This is a temportary function. The interface will change to
       
   594     ///a better one.
       
   595     Row addRow(Value l,const Expr &e, Value u) {
       
   596       Row r=addRow();
       
   597       setRow(r,l,e,u);
       
   598       return r;
       
   599     }
       
   600 
       
   601     ///Add a new row (i.e a new constaint) to the LP
       
   602 
       
   603     ///\param c is a linear expression (see \ref Constr)
       
   604     ///\return The created row.
       
   605     Row addRow(const Constr &c) {
       
   606       Row r=addRow();
       
   607       setRow(r,c);
       
   608       return r;
       
   609     }
       
   610 
       
   611     /// Set the lower bound of a column (i.e a variable)
       
   612 
       
   613     /// The upper bound of a variable (column) has to be given by an 
       
   614     /// extended number of type Value, i.e. a finite number of type 
       
   615     /// Value or -\ref INF.
       
   616     void colLowerBound(Col c, Value value) {
       
   617       _setColLowerBound(cols.floatingId(c.id),value);
       
   618     }
       
   619     /// Set the upper bound of a column (i.e a variable)
       
   620 
       
   621     /// The upper bound of a variable (column) has to be given by an 
       
   622     /// extended number of type Value, i.e. a finite number of type 
       
   623     /// Value or \ref INF.
       
   624     void colUpperBound(Col c, Value value) {
       
   625       _setColUpperBound(cols.floatingId(c.id),value);
       
   626     };
       
   627     /// Set the lower and the upper bounds of a column (i.e a variable)
       
   628 
       
   629     /// The lower and the upper bounds of
       
   630     /// a variable (column) have to be given by an 
       
   631     /// extended number of type Value, i.e. a finite number of type 
       
   632     /// Value, -\ref INF or \ref INF.
       
   633     void colBounds(Col c, Value lower, Value upper) {
       
   634       _setColLowerBound(cols.floatingId(c.id),lower);
       
   635       _setColUpperBound(cols.floatingId(c.id),upper);
       
   636     }
       
   637     
       
   638 //     /// Set the lower bound of a row (i.e a constraint)
       
   639 
       
   640 //     /// The lower bound of a linear expression (row) has to be given by an 
       
   641 //     /// extended number of type Value, i.e. a finite number of type 
       
   642 //     /// Value or -\ref INF.
       
   643 //     void rowLowerBound(Row r, Value value) {
       
   644 //       _setRowLowerBound(rows.floatingId(r.id),value);
       
   645 //     };
       
   646 //     /// Set the upper bound of a row (i.e a constraint)
       
   647 
       
   648 //     /// The upper bound of a linear expression (row) has to be given by an 
       
   649 //     /// extended number of type Value, i.e. a finite number of type 
       
   650 //     /// Value or \ref INF.
       
   651 //     void rowUpperBound(Row r, Value value) {
       
   652 //       _setRowUpperBound(rows.floatingId(r.id),value);
       
   653 //     };
       
   654 
       
   655     /// Set the lower and the upper bounds of a row (i.e a constraint)
       
   656 
       
   657     /// The lower and the upper bounds of
       
   658     /// a constraint (row) have to be given by an 
       
   659     /// extended number of type Value, i.e. a finite number of type 
       
   660     /// Value, -\ref INF or \ref INF.
       
   661     void rowBounds(Row c, Value lower, Value upper) {
       
   662       _setRowBounds(rows.floatingId(c.id),lower, upper);
       
   663       // _setRowUpperBound(rows.floatingId(c.id),upper);
       
   664     }
       
   665     
       
   666     ///Set an element of the objective function
       
   667     void objCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); };
       
   668     ///Set the objective function
       
   669     
       
   670     ///\param e is a linear expression of type \ref Expr.
       
   671     ///\bug The previous objective function is not cleared!
       
   672     void setObj(Expr e) {
       
   673       _clearObj();
       
   674       for (Expr::iterator i=e.begin(); i!=e.end(); ++i)
       
   675 	objCoeff((*i).first,(*i).second);
       
   676       obj_const_comp=e.constComp();
       
   677     }
       
   678 
       
   679     ///Maximize
       
   680     void max() { _setMax(); }
       
   681     ///Minimize
       
   682     void min() { _setMin(); }
       
   683 
       
   684     
       
   685     ///@}
       
   686 
       
   687 
       
   688     ///\name Solve the LP
       
   689 
       
   690     ///@{
       
   691 
       
   692     ///\e
       
   693     SolveExitStatus solve() { return _solve(); }
       
   694     
       
   695     ///@}
       
   696     
       
   697     ///\name Obtain the solution
       
   698 
       
   699     ///@{
       
   700 
       
   701     ///\e
       
   702     SolutionStatus primalStatus() {
       
   703       return _getPrimalStatus();
       
   704     }
       
   705 
       
   706     ///\e
       
   707     Value primal(Col c) { return _getPrimal(cols.floatingId(c.id)); }
       
   708 
       
   709     ///\e
       
   710 
       
   711     ///\return
       
   712     ///- \ref INF or -\ref INF means either infeasibility or unboundedness
       
   713     /// of the primal problem, depending on whether we minimize or maximize.
       
   714     ///- \ref NaN if no primal solution is found.
       
   715     ///- The (finite) objective value if an optimal solution is found.
       
   716     Value primalValue() { return _getPrimalValue()+obj_const_comp;}
       
   717     ///@}
       
   718     
       
   719   };  
       
   720 
       
   721   ///\e
       
   722   
       
   723   ///\relates LpSolverBase::Expr
       
   724   ///
       
   725   inline LpSolverBase::Expr operator+(const LpSolverBase::Expr &a,
       
   726 				      const LpSolverBase::Expr &b) 
       
   727   {
       
   728     LpSolverBase::Expr tmp(a);
       
   729     tmp+=b; ///\todo Doesn't STL have some special 'merge' algorithm?
       
   730     return tmp;
       
   731   }
       
   732   ///\e
       
   733   
       
   734   ///\relates LpSolverBase::Expr
       
   735   ///
       
   736   inline LpSolverBase::Expr operator-(const LpSolverBase::Expr &a,
       
   737 				      const LpSolverBase::Expr &b) 
       
   738   {
       
   739     LpSolverBase::Expr tmp(a);
       
   740     tmp-=b; ///\todo Doesn't STL have some special 'merge' algorithm?
       
   741     return tmp;
       
   742   }
       
   743   ///\e
       
   744   
       
   745   ///\relates LpSolverBase::Expr
       
   746   ///
       
   747   inline LpSolverBase::Expr operator*(const LpSolverBase::Expr &a,
       
   748 				      const LpSolverBase::Value &b) 
       
   749   {
       
   750     LpSolverBase::Expr tmp(a);
       
   751     tmp*=b; ///\todo Doesn't STL have some special 'merge' algorithm?
       
   752     return tmp;
       
   753   }
       
   754   
       
   755   ///\e
       
   756   
       
   757   ///\relates LpSolverBase::Expr
       
   758   ///
       
   759   inline LpSolverBase::Expr operator*(const LpSolverBase::Value &a,
       
   760 				      const LpSolverBase::Expr &b) 
       
   761   {
       
   762     LpSolverBase::Expr tmp(b);
       
   763     tmp*=a; ///\todo Doesn't STL have some special 'merge' algorithm?
       
   764     return tmp;
       
   765   }
       
   766   ///\e
       
   767   
       
   768   ///\relates LpSolverBase::Expr
       
   769   ///
       
   770   inline LpSolverBase::Expr operator/(const LpSolverBase::Expr &a,
       
   771 				      const LpSolverBase::Value &b) 
       
   772   {
       
   773     LpSolverBase::Expr tmp(a);
       
   774     tmp/=b; ///\todo Doesn't STL have some special 'merge' algorithm?
       
   775     return tmp;
       
   776   }
       
   777   
       
   778   ///\e
       
   779   
       
   780   ///\relates LpSolverBase::Constr
       
   781   ///
       
   782   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
       
   783 					 const LpSolverBase::Expr &f) 
       
   784   {
       
   785     return LpSolverBase::Constr(-LpSolverBase::INF,e-f,0);
       
   786   }
       
   787 
       
   788   ///\e
       
   789   
       
   790   ///\relates LpSolverBase::Constr
       
   791   ///
       
   792   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &e,
       
   793 					 const LpSolverBase::Expr &f) 
       
   794   {
       
   795     return LpSolverBase::Constr(e,f);
       
   796   }
       
   797 
       
   798   ///\e
       
   799   
       
   800   ///\relates LpSolverBase::Constr
       
   801   ///
       
   802   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
       
   803 					 const LpSolverBase::Value &f) 
       
   804   {
       
   805     return LpSolverBase::Constr(e,f);
       
   806   }
       
   807 
       
   808   ///\e
       
   809   
       
   810   ///\relates LpSolverBase::Constr
       
   811   ///
       
   812   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
       
   813 					 const LpSolverBase::Expr &f) 
       
   814   {
       
   815     return LpSolverBase::Constr(-LpSolverBase::INF,f-e,0);
       
   816   }
       
   817 
       
   818 
       
   819   ///\e
       
   820   
       
   821   ///\relates LpSolverBase::Constr
       
   822   ///
       
   823   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &e,
       
   824 					 const LpSolverBase::Expr &f) 
       
   825   {
       
   826     return LpSolverBase::Constr(f,e);
       
   827   }
       
   828 
       
   829 
       
   830   ///\e
       
   831   
       
   832   ///\relates LpSolverBase::Constr
       
   833   ///
       
   834   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
       
   835 					 const LpSolverBase::Value &f) 
       
   836   {
       
   837     return LpSolverBase::Constr(f,e);
       
   838   }
       
   839 
       
   840   ///\e
       
   841   
       
   842   ///\relates LpSolverBase::Constr
       
   843   ///
       
   844   inline LpSolverBase::Constr operator==(const LpSolverBase::Expr &e,
       
   845 					 const LpSolverBase::Expr &f) 
       
   846   {
       
   847     return LpSolverBase::Constr(0,e-f,0);
       
   848   }
       
   849 
       
   850   ///\e
       
   851   
       
   852   ///\relates LpSolverBase::Constr
       
   853   ///
       
   854   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &n,
       
   855 					 const LpSolverBase::Constr&c) 
       
   856   {
       
   857     LpSolverBase::Constr tmp(c);
       
   858     ///\todo Create an own exception type.
       
   859     if(!isnan(tmp.lowerBound())) throw LogicError();
       
   860     else tmp.lowerBound()=n;
       
   861     return tmp;
       
   862   }
       
   863   ///\e
       
   864   
       
   865   ///\relates LpSolverBase::Constr
       
   866   ///
       
   867   inline LpSolverBase::Constr operator<=(const LpSolverBase::Constr& c,
       
   868 					 const LpSolverBase::Value &n)
       
   869   {
       
   870     LpSolverBase::Constr tmp(c);
       
   871     ///\todo Create an own exception type.
       
   872     if(!isnan(tmp.upperBound())) throw LogicError();
       
   873     else tmp.upperBound()=n;
       
   874     return tmp;
       
   875   }
       
   876 
       
   877   ///\e
       
   878   
       
   879   ///\relates LpSolverBase::Constr
       
   880   ///
       
   881   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &n,
       
   882 					 const LpSolverBase::Constr&c) 
       
   883   {
       
   884     LpSolverBase::Constr tmp(c);
       
   885     ///\todo Create an own exception type.
       
   886     if(!isnan(tmp.upperBound())) throw LogicError();
       
   887     else tmp.upperBound()=n;
       
   888     return tmp;
       
   889   }
       
   890   ///\e
       
   891   
       
   892   ///\relates LpSolverBase::Constr
       
   893   ///
       
   894   inline LpSolverBase::Constr operator>=(const LpSolverBase::Constr& c,
       
   895 					 const LpSolverBase::Value &n)
       
   896   {
       
   897     LpSolverBase::Constr tmp(c);
       
   898     ///\todo Create an own exception type.
       
   899     if(!isnan(tmp.lowerBound())) throw LogicError();
       
   900     else tmp.lowerBound()=n;
       
   901     return tmp;
       
   902   }
       
   903 
       
   904 
       
   905 } //namespace lemon
       
   906 
       
   907 #endif //LEMON_LP_BASE_H