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