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