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