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