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