lemon/lp_base.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2185 e2bf51eab7f7
child 2260 4274224f8a7d
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

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