lemon/lp_base.h
author alpar
Thu, 09 Jun 2005 09:49:56 +0000
changeset 1459 2ee881cf30a8
parent 1445 4635352e5524
child 1460 7c58aabb9eea
permissions -rw-r--r--
- InDegMap fixed
- OutDegMap added
- test cases added for them both
     1 /* -*- C++ -*-
     2  * 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     ///Possible outcomes of an LP solving procedure
   112     enum SolveExitStatus {
   113       ///This means that the problem has been successfully solved: either
   114       ///an optimal solution has been found or infeasibility/unboundedness
   115       ///has been proved.
   116       SOLVED = 0,
   117       ///Any other case (including the case when some user specified limit has been exceeded)
   118       UNSOLVED = 1
   119     };
   120       
   121     ///\e
   122     enum SolutionStatus {
   123       ///Feasible solution has'n been found (but may exist).
   124 
   125       ///\todo NOTFOUND might be a better name.
   126       ///
   127       UNDEFINED = 0,
   128       ///The problem has no feasible solution
   129       INFEASIBLE = 1,
   130       ///Feasible solution found
   131       FEASIBLE = 2,
   132       ///Optimal solution exists and found
   133       OPTIMAL = 3,
   134       ///The cost function is unbounded
   135 
   136       ///\todo Give a feasible solution and an infinite ray (and the
   137       ///corresponding bases)
   138       INFINITE = 4
   139     };
   140       
   141     ///The floating point type used by the solver
   142     typedef double Value;
   143     ///The infinity constant
   144     static const Value INF;
   145     ///The not a number constant
   146     static const Value NaN;
   147     
   148     ///Refer to a column of the LP.
   149 
   150     ///This type is used to refer to a column of the LP.
   151     ///
   152     ///Its value remains valid and correct even after the addition or erase of
   153     ///other columns.
   154     ///
   155     ///\todo Document what can one do with a Col (INVALID, comparing,
   156     ///it is similar to Node/Edge)
   157     class Col {
   158     protected:
   159       int id;
   160       friend class LpSolverBase;
   161     public:
   162       typedef Value ExprValue;
   163       typedef True LpSolverCol;
   164       Col() {}
   165       Col(const Invalid&) : id(-1) {}
   166       bool operator<(Col c) const  {return id<c.id;}
   167       bool operator==(Col c) const  {return id==c.id;}
   168       bool operator!=(Col c) const  {return id==c.id;}
   169     };
   170 
   171     ///Refer to a row of the LP.
   172 
   173     ///This type is used to refer to a row of the LP.
   174     ///
   175     ///Its value remains valid and correct even after the addition or erase of
   176     ///other rows.
   177     ///
   178     ///\todo Document what can one do with a Row (INVALID, comparing,
   179     ///it is similar to Node/Edge)
   180     class Row {
   181     protected:
   182       int id;
   183       friend class LpSolverBase;
   184     public:
   185       typedef Value ExprValue;
   186       typedef True LpSolverRow;
   187       Row() {}
   188       Row(const Invalid&) : id(-1) {}
   189 
   190       bool operator<(Row c) const  {return id<c.id;}
   191       bool operator==(Row c) const  {return id==c.id;}
   192       bool operator!=(Row c) const  {return id==c.id;} 
   193    };
   194     
   195     ///Linear expression of variables and a constant component
   196     
   197     ///This data structure strores a linear expression of the variables
   198     ///(\ref Col "Col"s) and also has a constant component.
   199     ///
   200     ///There are several ways to access and modify the contents of this
   201     ///container.
   202     ///- Its it fully compatible with \c std::map<Col,double>, so for expamle
   203     ///if \c e is an Expr and \c v and \c w are of type \ref Col, then you can
   204     ///read and modify the coefficients like
   205     ///these.
   206     ///\code
   207     ///e[v]=5;
   208     ///e[v]+=12;
   209     ///e.erase(v);
   210     ///\endcode
   211     ///or you can also iterate through its elements.
   212     ///\code
   213     ///double s=0;
   214     ///for(LpSolverBase::Expr::iterator i=e.begin();i!=e.end();++i)
   215     ///  s+=i->second;
   216     ///\endcode
   217     ///(This code computes the sum of all coefficients).
   218     ///- Numbers (<tt>double</tt>'s)
   219     ///and variables (\ref Col "Col"s) directly convert to an
   220     ///\ref Expr and the usual linear operations are defined so  
   221     ///\code
   222     ///v+w
   223     ///2*v-3.12*(v-w/2)+2
   224     ///v*2.1+(3*v+(v*12+w+6)*3)/2
   225     ///\endcode
   226     ///are valid \ref Expr "Expr"essions.
   227     ///The usual assignment operations are also defined.
   228     ///\code
   229     ///e=v+w;
   230     ///e+=2*v-3.12*(v-w/2)+2;
   231     ///e*=3.4;
   232     ///e/=5;
   233     ///\endcode
   234     ///- The constant member can be set and read by \ref constComp()
   235     ///\code
   236     ///e.constComp()=12;
   237     ///double c=e.constComp();
   238     ///\endcode
   239     ///
   240     ///\note \ref clear() not only sets all coefficients to 0 but also
   241     ///clears the constant components.
   242     ///
   243     ///\sa Constr
   244     ///
   245     class Expr : public std::map<Col,Value>
   246     {
   247     public:
   248       typedef LpSolverBase::Col Key; 
   249       typedef LpSolverBase::Value Value;
   250       
   251     protected:
   252       typedef std::map<Col,Value> Base;
   253       
   254       Value const_comp;
   255   public:
   256       typedef True IsLinExpression;
   257       ///\e
   258       Expr() : Base(), const_comp(0) { }
   259       ///\e
   260       Expr(const Key &v) : const_comp(0) {
   261 	Base::insert(std::make_pair(v, 1));
   262       }
   263       ///\e
   264       Expr(const Value &v) : const_comp(v) {}
   265       ///\e
   266       void set(const Key &v,const Value &c) {
   267 	Base::insert(std::make_pair(v, c));
   268       }
   269       ///\e
   270       Value &constComp() { return const_comp; }
   271       ///\e
   272       const Value &constComp() const { return const_comp; }
   273       
   274       ///Removes the components with zero coefficient.
   275       void simplify() {
   276 	for (Base::iterator i=Base::begin(); i!=Base::end();) {
   277 	  Base::iterator j=i;
   278 	  ++j;
   279 	  if ((*i).second==0) Base::erase(i);
   280 	  j=i;
   281 	}
   282       }
   283 
   284       ///Sets all coefficients and the constant component to 0.
   285       void clear() {
   286 	Base::clear();
   287 	const_comp=0;
   288       }
   289 
   290       ///\e
   291       Expr &operator+=(const Expr &e) {
   292 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
   293 	  (*this)[j->first]+=j->second;
   294 	///\todo it might be speeded up using "hints"
   295 	const_comp+=e.const_comp;
   296 	return *this;
   297       }
   298       ///\e
   299       Expr &operator-=(const Expr &e) {
   300 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
   301 	  (*this)[j->first]-=j->second;
   302 	const_comp-=e.const_comp;
   303 	return *this;
   304       }
   305       ///\e
   306       Expr &operator*=(const Value &c) {
   307 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
   308 	  j->second*=c;
   309 	const_comp*=c;
   310 	return *this;
   311       }
   312       ///\e
   313       Expr &operator/=(const Value &c) {
   314 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
   315 	  j->second/=c;
   316 	const_comp/=c;
   317 	return *this;
   318       }
   319     };
   320     
   321     ///Linear constraint
   322 
   323     ///This data stucture represents a linear constraint in the LP.
   324     ///Basically it is a linear expression with a lower or an upper bound
   325     ///(or both). These parts of the constraint can be obtained by the member
   326     ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
   327     ///respectively.
   328     ///There are two ways to construct a constraint.
   329     ///- You can set the linear expression and the bounds directly
   330     ///  by the functions above.
   331     ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
   332     ///  are defined between expressions, or even between constraints whenever
   333     ///  it makes sense. Therefore if \c e and \c f are linear expressions and
   334     ///  \c s and \c t are numbers, then the followings are valid expressions
   335     ///  and thus they can be used directly e.g. in \ref addRow() whenever
   336     ///  it makes sense.
   337     ///  \code
   338     ///  e<=s
   339     ///  e<=f
   340     ///  s<=e<=t
   341     ///  e>=t
   342     ///  \endcode
   343     ///\warning The validity of a constraint is checked only at run time, so
   344     ///e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will compile, but will throw a
   345     ///\ref LogicError exception.
   346     class Constr
   347     {
   348     public:
   349       typedef LpSolverBase::Expr Expr;
   350       typedef Expr::Key Key;
   351       typedef Expr::Value Value;
   352       
   353 //       static const Value INF;
   354 //       static const Value NaN;
   355 
   356     protected:
   357       Expr _expr;
   358       Value _lb,_ub;
   359     public:
   360       ///\e
   361       Constr() : _expr(), _lb(NaN), _ub(NaN) {}
   362       ///\e
   363       Constr(Value lb,const Expr &e,Value ub) :
   364 	_expr(e), _lb(lb), _ub(ub) {}
   365       ///\e
   366       Constr(const Expr &e,Value ub) : 
   367 	_expr(e), _lb(NaN), _ub(ub) {}
   368       ///\e
   369       Constr(Value lb,const Expr &e) :
   370 	_expr(e), _lb(lb), _ub(NaN) {}
   371       ///\e
   372       Constr(const Expr &e) : 
   373 	_expr(e), _lb(NaN), _ub(NaN) {}
   374       ///\e
   375       void clear() 
   376       {
   377 	_expr.clear();
   378 	_lb=_ub=NaN;
   379       }
   380 
   381       ///Reference to the linear expression 
   382       Expr &expr() { return _expr; }
   383       ///Cont reference to the linear expression 
   384       const Expr &expr() const { return _expr; }
   385       ///Reference to the lower bound.
   386 
   387       ///\return
   388       ///- -\ref INF: the constraint is lower unbounded.
   389       ///- -\ref NaN: lower bound has not been set.
   390       ///- finite number: the lower bound
   391       Value &lowerBound() { return _lb; }
   392       ///The const version of \ref lowerBound()
   393       const Value &lowerBound() const { return _lb; }
   394       ///Reference to the upper bound.
   395 
   396       ///\return
   397       ///- -\ref INF: the constraint is upper unbounded.
   398       ///- -\ref NaN: upper bound has not been set.
   399       ///- finite number: the upper bound
   400       Value &upperBound() { return _ub; }
   401       ///The const version of \ref upperBound()
   402       const Value &upperBound() const { return _ub; }
   403       ///Is the constraint lower bounded?
   404       bool lowerBounded() const { 
   405 	using namespace std;
   406 	return finite(_lb);
   407       }
   408       ///Is the constraint upper bounded?
   409       bool upperBounded() const {
   410 	using namespace std;
   411 	return finite(_ub);
   412       }
   413     };
   414     
   415     ///Linear expression of rows
   416     
   417     ///This data structure represents a column of the matrix,
   418     ///thas is it strores a linear expression of the dual variables
   419     ///(\ref Row "Row"s).
   420     ///
   421     ///There are several ways to access and modify the contents of this
   422     ///container.
   423     ///- Its it fully compatible with \c std::map<Row,double>, so for expamle
   424     ///if \c e is an DualExpr and \c v
   425     ///and \c w are of type \ref Row, then you can
   426     ///read and modify the coefficients like
   427     ///these.
   428     ///\code
   429     ///e[v]=5;
   430     ///e[v]+=12;
   431     ///e.erase(v);
   432     ///\endcode
   433     ///or you can also iterate through its elements.
   434     ///\code
   435     ///double s=0;
   436     ///for(LpSolverBase::DualExpr::iterator i=e.begin();i!=e.end();++i)
   437     ///  s+=i->second;
   438     ///\endcode
   439     ///(This code computes the sum of all coefficients).
   440     ///- Numbers (<tt>double</tt>'s)
   441     ///and variables (\ref Row "Row"s) directly convert to an
   442     ///\ref DualExpr and the usual linear operations are defined so  
   443     ///\code
   444     ///v+w
   445     ///2*v-3.12*(v-w/2)
   446     ///v*2.1+(3*v+(v*12+w)*3)/2
   447     ///\endcode
   448     ///are valid \ref DualExpr "DualExpr"essions.
   449     ///The usual assignment operations are also defined.
   450     ///\code
   451     ///e=v+w;
   452     ///e+=2*v-3.12*(v-w/2);
   453     ///e*=3.4;
   454     ///e/=5;
   455     ///\endcode
   456     ///
   457     ///\sa Expr
   458     ///
   459     class DualExpr : public std::map<Row,Value>
   460     {
   461     public:
   462       typedef LpSolverBase::Row Key; 
   463       typedef LpSolverBase::Value Value;
   464       
   465     protected:
   466       typedef std::map<Row,Value> Base;
   467       
   468     public:
   469       typedef True IsLinExpression;
   470       ///\e
   471       DualExpr() : Base() { }
   472       ///\e
   473       DualExpr(const Key &v) {
   474 	Base::insert(std::make_pair(v, 1));
   475       }
   476       ///\e
   477       DualExpr(const Value &v) {}
   478       ///\e
   479       void set(const Key &v,const Value &c) {
   480 	Base::insert(std::make_pair(v, c));
   481       }
   482       
   483       ///Removes the components with zero coefficient.
   484       void simplify() {
   485 	for (Base::iterator i=Base::begin(); i!=Base::end();) {
   486 	  Base::iterator j=i;
   487 	  ++j;
   488 	  if ((*i).second==0) Base::erase(i);
   489 	  j=i;
   490 	}
   491       }
   492 
   493       ///Sets all coefficients to 0.
   494       void clear() {
   495 	Base::clear();
   496       }
   497 
   498       ///\e
   499       DualExpr &operator+=(const DualExpr &e) {
   500 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
   501 	  (*this)[j->first]+=j->second;
   502 	///\todo it might be speeded up using "hints"
   503 	return *this;
   504       }
   505       ///\e
   506       DualExpr &operator-=(const DualExpr &e) {
   507 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
   508 	  (*this)[j->first]-=j->second;
   509 	return *this;
   510       }
   511       ///\e
   512       DualExpr &operator*=(const Value &c) {
   513 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
   514 	  j->second*=c;
   515 	return *this;
   516       }
   517       ///\e
   518       DualExpr &operator/=(const Value &c) {
   519 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
   520 	  j->second/=c;
   521 	return *this;
   522       }
   523     };
   524     
   525 
   526   protected:
   527     _FixId rows;
   528     _FixId cols;
   529 
   530     //Abstract virtual functions
   531     virtual LpSolverBase &_newLp() = 0;
   532     virtual LpSolverBase &_copyLp(){
   533       ///\todo This should be implemented here, too,  when we have problem retrieving routines. It can be overriden.
   534 
   535       //Starting:
   536       LpSolverBase & newlp(_newLp());
   537       return newlp;
   538       //return *(LpSolverBase*)0;
   539     };
   540 
   541     virtual int _addCol() = 0;
   542     virtual int _addRow() = 0;
   543     virtual void _setRowCoeffs(int i, 
   544 			       int length,
   545                                int  const * indices, 
   546                                Value  const * values ) = 0;
   547     virtual void _setColCoeffs(int i, 
   548 			       int length,
   549                                int  const * indices, 
   550                                Value  const * values ) = 0;
   551     virtual void _setCoeff(int row, int col, Value value) = 0;
   552     virtual void _setColLowerBound(int i, Value value) = 0;
   553     virtual void _setColUpperBound(int i, Value value) = 0;
   554 //     virtual void _setRowLowerBound(int i, Value value) = 0;
   555 //     virtual void _setRowUpperBound(int i, Value value) = 0;
   556     virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
   557     virtual void _setObjCoeff(int i, Value obj_coef) = 0;
   558     virtual void _clearObj()=0;
   559 //     virtual void _setObj(int length,
   560 //                          int  const * indices, 
   561 //                          Value  const * values ) = 0;
   562     virtual SolveExitStatus _solve() = 0;
   563     virtual Value _getPrimal(int i) = 0;
   564     virtual Value _getPrimalValue() = 0;
   565     virtual SolutionStatus _getPrimalStatus() = 0;
   566     virtual void _setMax() = 0;
   567     virtual void _setMin() = 0;
   568     
   569     //Own protected stuff
   570     
   571     //Constant component of the objective function
   572     Value obj_const_comp;
   573     
   574 
   575 
   576     
   577   public:
   578 
   579     ///\e
   580     LpSolverBase() : obj_const_comp(0) {}
   581 
   582     ///\e
   583     virtual ~LpSolverBase() {}
   584 
   585     ///Creates a new LP problem
   586     LpSolverBase &newLp() {return _newLp();}
   587     ///Makes a copy of the LP problem
   588     LpSolverBase &copyLp() {return _copyLp();}
   589     
   590     ///\name Build up and modify of the LP
   591 
   592     ///@{
   593 
   594     ///Add a new empty column (i.e a new variable) to the LP
   595     Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;}
   596 
   597     ///\brief Adds several new columns
   598     ///(i.e a variables) at once
   599     ///
   600     ///This magic function takes a container as its argument
   601     ///and fills its elements
   602     ///with new columns (i.e. variables)
   603     ///\param t can be
   604     ///- a standard STL compatible iterable container with
   605     ///\ref Col as its \c values_type
   606     ///like
   607     ///\code
   608     ///std::vector<LpSolverBase::Col>
   609     ///std::list<LpSolverBase::Col>
   610     ///\endcode
   611     ///- a standard STL compatible iterable container with
   612     ///\ref Col as its \c mapped_type
   613     ///like
   614     ///\code
   615     ///std::map<AnyType,LpSolverBase::Col>
   616     ///\endcode
   617     ///- an iterable lemon \ref concept::WriteMap "write map" like 
   618     ///\code
   619     ///ListGraph::NodeMap<LpSolverBase::Col>
   620     ///ListGraph::EdgeMap<LpSolverBase::Col>
   621     ///\endcode
   622     ///\return The number of the created column.
   623 #ifdef DOXYGEN
   624     template<class T>
   625     int addColSet(T &t) { return 0;} 
   626 #else
   627     template<class T>
   628     typename enable_if<typename T::value_type::LpSolverCol,int>::type
   629     addColSet(T &t,dummy<0> = 0) {
   630       int s=0;
   631       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
   632       return s;
   633     }
   634     template<class T>
   635     typename enable_if<typename T::value_type::second_type::LpSolverCol,
   636 		       int>::type
   637     addColSet(T &t,dummy<1> = 1) { 
   638       int s=0;
   639       for(typename T::iterator i=t.begin();i!=t.end();++i) {
   640 	i->second=addCol();
   641 	s++;
   642       }
   643       return s;
   644     }
   645     template<class T>
   646     typename enable_if<typename T::ValueSet::value_type::LpSolverCol,
   647 		       int>::type
   648     addColSet(T &t,dummy<2> = 2) { 
   649       ///\bug <tt>return addColSet(t.valueSet());</tt> should also work.
   650       int s=0;
   651       for(typename T::ValueSet::iterator i=t.valueSet().begin();
   652 	  i!=t.valueSet().end();
   653 	  ++i)
   654 	{
   655 	  *i=addCol();
   656 	  s++;
   657 	}
   658       return s;
   659     }
   660 #endif
   661 
   662     ///Set a column (i.e a dual constraint) of the LP
   663 
   664     ///\param c is the column to be modified
   665     ///\param e is a dual linear expression (see \ref DualExpr)
   666     ///\bug This is a temportary function. The interface will change to
   667     ///a better one.
   668     void setCol(Col c,const DualExpr &e) {
   669       std::vector<int> indices;
   670       std::vector<Value> values;
   671       indices.push_back(0);
   672       values.push_back(0);
   673       for(DualExpr::const_iterator i=e.begin(); i!=e.end(); ++i)
   674 	if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
   675 	  indices.push_back(cols.floatingId((*i).first.id));
   676 	  values.push_back((*i).second);
   677 	}
   678       _setColCoeffs(cols.floatingId(c.id),indices.size()-1,
   679 		    &indices[0],&values[0]);
   680     }
   681 
   682     ///Add a new column to the LP
   683 
   684     ///\param e is a dual linear expression (see \ref DualExpr)
   685     ///\param obj is the corresponding component of the objective
   686     ///function. It is 0 by default.
   687     ///\return The created column.
   688     ///\bug This is a temportary function. The interface will change to
   689     ///a better one.
   690     Col addCol(Value l,const DualExpr &e, Value obj=0) {
   691       Col c=addCol();
   692       setCol(c,e);
   693       objCoeff(c,0);
   694       return c;
   695     }
   696 
   697     ///Add a new empty row (i.e a new constraint) to the LP
   698 
   699     ///This function adds a new empty row (i.e a new constraint) to the LP.
   700     ///\return The created row
   701     Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;}
   702 
   703     ///\brief Adds several new row
   704     ///(i.e a variables) at once
   705     ///
   706     ///This magic function takes a container as its argument
   707     ///and fills its elements
   708     ///with new row (i.e. variables)
   709     ///\param t can be
   710     ///- a standard STL compatible iterable container with
   711     ///\ref Row as its \c values_type
   712     ///like
   713     ///\code
   714     ///std::vector<LpSolverBase::Row>
   715     ///std::list<LpSolverBase::Row>
   716     ///\endcode
   717     ///- a standard STL compatible iterable container with
   718     ///\ref Row as its \c mapped_type
   719     ///like
   720     ///\code
   721     ///std::map<AnyType,LpSolverBase::Row>
   722     ///\endcode
   723     ///- an iterable lemon \ref concept::WriteMap "write map" like 
   724     ///\code
   725     ///ListGraph::NodeMap<LpSolverBase::Row>
   726     ///ListGraph::EdgeMap<LpSolverBase::Row>
   727     ///\endcode
   728     ///\return The number of rows created.
   729 #ifdef DOXYGEN
   730     template<class T>
   731     int addRowSet(T &t) { return 0;} 
   732 #else
   733     template<class T>
   734     typename enable_if<typename T::value_type::LpSolverRow,int>::type
   735     addRowSet(T &t,dummy<0> = 0) {
   736       int s=0;
   737       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
   738       return s;
   739     }
   740     template<class T>
   741     typename enable_if<typename T::value_type::second_type::LpSolverRow,
   742 		       int>::type
   743     addRowSet(T &t,dummy<1> = 1) { 
   744       int s=0;
   745       for(typename T::iterator i=t.begin();i!=t.end();++i) {
   746 	i->second=addRow();
   747 	s++;
   748       }
   749       return s;
   750     }
   751     template<class T>
   752     typename enable_if<typename T::ValueSet::value_type::LpSolverRow,
   753 		       int>::type
   754     addRowSet(T &t,dummy<2> = 2) { 
   755       ///\bug <tt>return addRowSet(t.valueSet());</tt> should also work.
   756       int s=0;
   757       for(typename T::ValueSet::iterator i=t.valueSet().begin();
   758 	  i!=t.valueSet().end();
   759 	  ++i)
   760 	{
   761 	  *i=addRow();
   762 	  s++;
   763 	}
   764       return s;
   765     }
   766 #endif
   767 
   768     ///Set a row (i.e a constraint) of the LP
   769 
   770     ///\param r is the row to be modified
   771     ///\param l is lower bound (-\ref INF means no bound)
   772     ///\param e is a linear expression (see \ref Expr)
   773     ///\param u is the upper bound (\ref INF means no bound)
   774     ///\bug This is a temportary function. The interface will change to
   775     ///a better one.
   776     ///\todo Option to control whether a constraint with a single variable is
   777     ///added or not.
   778     void setRow(Row r, Value l,const Expr &e, Value u) {
   779       std::vector<int> indices;
   780       std::vector<Value> values;
   781       indices.push_back(0);
   782       values.push_back(0);
   783       for(Expr::const_iterator i=e.begin(); i!=e.end(); ++i)
   784 	if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
   785 	  indices.push_back(cols.floatingId((*i).first.id));
   786 	  values.push_back((*i).second);
   787 	}
   788       _setRowCoeffs(rows.floatingId(r.id),indices.size()-1,
   789 		    &indices[0],&values[0]);
   790 //       _setRowLowerBound(rows.floatingId(r.id),l-e.constComp());
   791 //       _setRowUpperBound(rows.floatingId(r.id),u-e.constComp());
   792        _setRowBounds(rows.floatingId(r.id),l-e.constComp(),u-e.constComp());
   793     }
   794 
   795     ///Set a row (i.e a constraint) of the LP
   796 
   797     ///\param r is the row to be modified
   798     ///\param c is a linear expression (see \ref Constr)
   799     void setRow(Row r, const Constr &c) {
   800       setRow(r,
   801 	     c.lowerBounded()?c.lowerBound():-INF,
   802 	     c.expr(),
   803 	     c.upperBounded()?c.upperBound():INF);
   804     }
   805 
   806     ///Add a new row (i.e a new constraint) to the LP
   807 
   808     ///\param l is the lower bound (-\ref INF means no bound)
   809     ///\param e is a linear expression (see \ref Expr)
   810     ///\param u is the upper bound (\ref INF means no bound)
   811     ///\return The created row.
   812     ///\bug This is a temportary function. The interface will change to
   813     ///a better one.
   814     Row addRow(Value l,const Expr &e, Value u) {
   815       Row r=addRow();
   816       setRow(r,l,e,u);
   817       return r;
   818     }
   819 
   820     ///Add a new row (i.e a new constraint) to the LP
   821 
   822     ///\param c is a linear expression (see \ref Constr)
   823     ///\return The created row.
   824     Row addRow(const Constr &c) {
   825       Row r=addRow();
   826       setRow(r,c);
   827       return r;
   828     }
   829 
   830     ///Set an element of the coefficient matrix of the LP
   831 
   832     ///\param r is the row of the element to be modified
   833     ///\param c is the coloumn of the element to be modified
   834     ///\param val is the new value of the coefficient
   835     void setCoeff(Row r, Col c, Value val){
   836       _setCoeff(rows.floatingId(r.id),cols.floatingId(c.id), val);
   837     }
   838 
   839     /// Set the lower bound of a column (i.e a variable)
   840 
   841     /// The upper bound of a variable (column) has to be given by an 
   842     /// extended number of type Value, i.e. a finite number of type 
   843     /// Value or -\ref INF.
   844     void colLowerBound(Col c, Value value) {
   845       _setColLowerBound(cols.floatingId(c.id),value);
   846     }
   847     /// Set the upper bound of a column (i.e a variable)
   848 
   849     /// The upper bound of a variable (column) has to be given by an 
   850     /// extended number of type Value, i.e. a finite number of type 
   851     /// Value or \ref INF.
   852     void colUpperBound(Col c, Value value) {
   853       _setColUpperBound(cols.floatingId(c.id),value);
   854     };
   855     /// Set the lower and the upper bounds of a column (i.e a variable)
   856 
   857     /// The lower and the upper bounds of
   858     /// a variable (column) have to be given by an 
   859     /// extended number of type Value, i.e. a finite number of type 
   860     /// Value, -\ref INF or \ref INF.
   861     void colBounds(Col c, Value lower, Value upper) {
   862       _setColLowerBound(cols.floatingId(c.id),lower);
   863       _setColUpperBound(cols.floatingId(c.id),upper);
   864     }
   865     
   866 //     /// Set the lower bound of a row (i.e a constraint)
   867 
   868 //     /// The lower bound of a linear expression (row) has to be given by an 
   869 //     /// extended number of type Value, i.e. a finite number of type 
   870 //     /// Value or -\ref INF.
   871 //     void rowLowerBound(Row r, Value value) {
   872 //       _setRowLowerBound(rows.floatingId(r.id),value);
   873 //     };
   874 //     /// Set the upper bound of a row (i.e a constraint)
   875 
   876 //     /// The upper bound of a linear expression (row) has to be given by an 
   877 //     /// extended number of type Value, i.e. a finite number of type 
   878 //     /// Value or \ref INF.
   879 //     void rowUpperBound(Row r, Value value) {
   880 //       _setRowUpperBound(rows.floatingId(r.id),value);
   881 //     };
   882 
   883     /// Set the lower and the upper bounds of a row (i.e a constraint)
   884 
   885     /// The lower and the upper bounds of
   886     /// a constraint (row) have to be given by an 
   887     /// extended number of type Value, i.e. a finite number of type 
   888     /// Value, -\ref INF or \ref INF.
   889     void rowBounds(Row c, Value lower, Value upper) {
   890       _setRowBounds(rows.floatingId(c.id),lower, upper);
   891       // _setRowUpperBound(rows.floatingId(c.id),upper);
   892     }
   893     
   894     ///Set an element of the objective function
   895     void objCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); };
   896     ///Set the objective function
   897     
   898     ///\param e is a linear expression of type \ref Expr.
   899     ///\bug The previous objective function is not cleared!
   900     void setObj(Expr e) {
   901       _clearObj();
   902       for (Expr::iterator i=e.begin(); i!=e.end(); ++i)
   903 	objCoeff((*i).first,(*i).second);
   904       obj_const_comp=e.constComp();
   905     }
   906 
   907     ///Maximize
   908     void max() { _setMax(); }
   909     ///Minimize
   910     void min() { _setMin(); }
   911 
   912     
   913     ///@}
   914 
   915 
   916     ///\name Solve the LP
   917 
   918     ///@{
   919 
   920     ///\e Solve the LP problem at hand
   921     ///
   922     ///\return The result of the optimization procedure. Possible values and their meanings can be found in the documentation of \ref SolveExitStatus.
   923     ///
   924     ///\todo Which method is used to solve the problem
   925     SolveExitStatus solve() { return _solve(); }
   926     
   927     ///@}
   928     
   929     ///\name Obtain the solution
   930 
   931     ///@{
   932 
   933     ///\e 
   934     SolutionStatus primalStatus() {
   935       return _getPrimalStatus();
   936     }
   937 
   938     ///\e
   939     Value primal(Col c) { return _getPrimal(cols.floatingId(c.id)); }
   940 
   941     ///\e
   942 
   943     ///\return
   944     ///- \ref INF or -\ref INF means either infeasibility or unboundedness
   945     /// of the primal problem, depending on whether we minimize or maximize.
   946     ///- \ref NaN if no primal solution is found.
   947     ///- The (finite) objective value if an optimal solution is found.
   948     Value primalValue() { return _getPrimalValue()+obj_const_comp;}
   949     ///@}
   950     
   951   };  
   952 
   953   ///\e
   954   
   955   ///\relates LpSolverBase::Expr
   956   ///
   957   inline LpSolverBase::Expr operator+(const LpSolverBase::Expr &a,
   958 				      const LpSolverBase::Expr &b) 
   959   {
   960     LpSolverBase::Expr tmp(a);
   961     tmp+=b; ///\todo Doesn't STL have some special 'merge' algorithm?
   962     return tmp;
   963   }
   964   ///\e
   965   
   966   ///\relates LpSolverBase::Expr
   967   ///
   968   inline LpSolverBase::Expr operator-(const LpSolverBase::Expr &a,
   969 				      const LpSolverBase::Expr &b) 
   970   {
   971     LpSolverBase::Expr tmp(a);
   972     tmp-=b; ///\todo Doesn't STL have some special 'merge' algorithm?
   973     return tmp;
   974   }
   975   ///\e
   976   
   977   ///\relates LpSolverBase::Expr
   978   ///
   979   inline LpSolverBase::Expr operator*(const LpSolverBase::Expr &a,
   980 				      const LpSolverBase::Value &b) 
   981   {
   982     LpSolverBase::Expr tmp(a);
   983     tmp*=b; ///\todo Doesn't STL have some special 'merge' algorithm?
   984     return tmp;
   985   }
   986   
   987   ///\e
   988   
   989   ///\relates LpSolverBase::Expr
   990   ///
   991   inline LpSolverBase::Expr operator*(const LpSolverBase::Value &a,
   992 				      const LpSolverBase::Expr &b) 
   993   {
   994     LpSolverBase::Expr tmp(b);
   995     tmp*=a; ///\todo Doesn't STL have some special 'merge' algorithm?
   996     return tmp;
   997   }
   998   ///\e
   999   
  1000   ///\relates LpSolverBase::Expr
  1001   ///
  1002   inline LpSolverBase::Expr operator/(const LpSolverBase::Expr &a,
  1003 				      const LpSolverBase::Value &b) 
  1004   {
  1005     LpSolverBase::Expr tmp(a);
  1006     tmp/=b; ///\todo Doesn't STL have some special 'merge' algorithm?
  1007     return tmp;
  1008   }
  1009   
  1010   ///\e
  1011   
  1012   ///\relates LpSolverBase::Constr
  1013   ///
  1014   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
  1015 					 const LpSolverBase::Expr &f) 
  1016   {
  1017     return LpSolverBase::Constr(-LpSolverBase::INF,e-f,0);
  1018   }
  1019 
  1020   ///\e
  1021   
  1022   ///\relates LpSolverBase::Constr
  1023   ///
  1024   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &e,
  1025 					 const LpSolverBase::Expr &f) 
  1026   {
  1027     return LpSolverBase::Constr(e,f);
  1028   }
  1029 
  1030   ///\e
  1031   
  1032   ///\relates LpSolverBase::Constr
  1033   ///
  1034   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
  1035 					 const LpSolverBase::Value &f) 
  1036   {
  1037     return LpSolverBase::Constr(e,f);
  1038   }
  1039 
  1040   ///\e
  1041   
  1042   ///\relates LpSolverBase::Constr
  1043   ///
  1044   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
  1045 					 const LpSolverBase::Expr &f) 
  1046   {
  1047     return LpSolverBase::Constr(-LpSolverBase::INF,f-e,0);
  1048   }
  1049 
  1050 
  1051   ///\e
  1052   
  1053   ///\relates LpSolverBase::Constr
  1054   ///
  1055   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &e,
  1056 					 const LpSolverBase::Expr &f) 
  1057   {
  1058     return LpSolverBase::Constr(f,e);
  1059   }
  1060 
  1061 
  1062   ///\e
  1063   
  1064   ///\relates LpSolverBase::Constr
  1065   ///
  1066   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
  1067 					 const LpSolverBase::Value &f) 
  1068   {
  1069     return LpSolverBase::Constr(f,e);
  1070   }
  1071 
  1072   ///\e
  1073   
  1074   ///\relates LpSolverBase::Constr
  1075   ///
  1076   inline LpSolverBase::Constr operator==(const LpSolverBase::Expr &e,
  1077 					 const LpSolverBase::Expr &f) 
  1078   {
  1079     return LpSolverBase::Constr(0,e-f,0);
  1080   }
  1081 
  1082   ///\e
  1083   
  1084   ///\relates LpSolverBase::Constr
  1085   ///
  1086   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &n,
  1087 					 const LpSolverBase::Constr&c) 
  1088   {
  1089     LpSolverBase::Constr tmp(c);
  1090     ///\todo Create an own exception type.
  1091     if(!isnan(tmp.lowerBound())) throw LogicError();
  1092     else tmp.lowerBound()=n;
  1093     return tmp;
  1094   }
  1095   ///\e
  1096   
  1097   ///\relates LpSolverBase::Constr
  1098   ///
  1099   inline LpSolverBase::Constr operator<=(const LpSolverBase::Constr& c,
  1100 					 const LpSolverBase::Value &n)
  1101   {
  1102     LpSolverBase::Constr tmp(c);
  1103     ///\todo Create an own exception type.
  1104     if(!isnan(tmp.upperBound())) throw LogicError();
  1105     else tmp.upperBound()=n;
  1106     return tmp;
  1107   }
  1108 
  1109   ///\e
  1110   
  1111   ///\relates LpSolverBase::Constr
  1112   ///
  1113   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &n,
  1114 					 const LpSolverBase::Constr&c) 
  1115   {
  1116     LpSolverBase::Constr tmp(c);
  1117     ///\todo Create an own exception type.
  1118     if(!isnan(tmp.upperBound())) throw LogicError();
  1119     else tmp.upperBound()=n;
  1120     return tmp;
  1121   }
  1122   ///\e
  1123   
  1124   ///\relates LpSolverBase::Constr
  1125   ///
  1126   inline LpSolverBase::Constr operator>=(const LpSolverBase::Constr& c,
  1127 					 const LpSolverBase::Value &n)
  1128   {
  1129     LpSolverBase::Constr tmp(c);
  1130     ///\todo Create an own exception type.
  1131     if(!isnan(tmp.lowerBound())) throw LogicError();
  1132     else tmp.lowerBound()=n;
  1133     return tmp;
  1134   }
  1135 
  1136   ///\e
  1137   
  1138   ///\relates LpSolverBase::DualExpr
  1139   ///
  1140   inline LpSolverBase::DualExpr operator+(const LpSolverBase::DualExpr &a,
  1141 				      const LpSolverBase::DualExpr &b) 
  1142   {
  1143     LpSolverBase::DualExpr tmp(a);
  1144     tmp+=b; ///\todo Doesn't STL have some special 'merge' algorithm?
  1145     return tmp;
  1146   }
  1147   ///\e
  1148   
  1149   ///\relates LpSolverBase::DualExpr
  1150   ///
  1151   inline LpSolverBase::DualExpr operator-(const LpSolverBase::DualExpr &a,
  1152 				      const LpSolverBase::DualExpr &b) 
  1153   {
  1154     LpSolverBase::DualExpr tmp(a);
  1155     tmp-=b; ///\todo Doesn't STL have some special 'merge' algorithm?
  1156     return tmp;
  1157   }
  1158   ///\e
  1159   
  1160   ///\relates LpSolverBase::DualExpr
  1161   ///
  1162   inline LpSolverBase::DualExpr operator*(const LpSolverBase::DualExpr &a,
  1163 				      const LpSolverBase::Value &b) 
  1164   {
  1165     LpSolverBase::DualExpr tmp(a);
  1166     tmp*=b; ///\todo Doesn't STL have some special 'merge' algorithm?
  1167     return tmp;
  1168   }
  1169   
  1170   ///\e
  1171   
  1172   ///\relates LpSolverBase::DualExpr
  1173   ///
  1174   inline LpSolverBase::DualExpr operator*(const LpSolverBase::Value &a,
  1175 				      const LpSolverBase::DualExpr &b) 
  1176   {
  1177     LpSolverBase::DualExpr tmp(b);
  1178     tmp*=a; ///\todo Doesn't STL have some special 'merge' algorithm?
  1179     return tmp;
  1180   }
  1181   ///\e
  1182   
  1183   ///\relates LpSolverBase::DualExpr
  1184   ///
  1185   inline LpSolverBase::DualExpr operator/(const LpSolverBase::DualExpr &a,
  1186 				      const LpSolverBase::Value &b) 
  1187   {
  1188     LpSolverBase::DualExpr tmp(a);
  1189     tmp/=b; ///\todo Doesn't STL have some special 'merge' algorithm?
  1190     return tmp;
  1191   }
  1192   
  1193 
  1194 } //namespace lemon
  1195 
  1196 #endif //LEMON_LP_BASE_H