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