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