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