lemon/lp_base.h
author Peter Kovacs <kpeter@inf.elte.hu>
Sun, 29 Mar 2009 23:08:20 +0200
changeset 550 c5fd2d996909
parent 490 2eb5c8ca2c91
child 568 745e182d0139
permissions -rw-r--r--
Various doc improvements (#248)
- Rename all the ugly template parameters (too long and/or starting
with an underscore).
- Rename function parameters starting with an underscore.
- Extend the doc for many classes.
- Use LaTeX-style O(...) expressions only for the complicated ones.
- A lot of small unification changes.
- Small fixes.
- Some other improvements.
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     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/assert.h>
    30 
    31 #include<lemon/core.h>
    32 #include<lemon/bits/solver_bits.h>
    33 
    34 ///\file
    35 ///\brief The interface of the LP solver interface.
    36 ///\ingroup lp_group
    37 namespace lemon {
    38 
    39   ///Common base class for LP and MIP solvers
    40 
    41   ///Usually this class is not used directly, please use one of the concrete
    42   ///implementations of the solver interface.
    43   ///\ingroup lp_group
    44   class LpBase {
    45 
    46   protected:
    47 
    48     _solver_bits::VarIndex rows;
    49     _solver_bits::VarIndex cols;
    50 
    51   public:
    52 
    53     ///Possible outcomes of an LP solving procedure
    54     enum SolveExitStatus {
    55       ///This means that the problem has been successfully solved: either
    56       ///an optimal solution has been found or infeasibility/unboundedness
    57       ///has been proved.
    58       SOLVED = 0,
    59       ///Any other case (including the case when some user specified
    60       ///limit has been exceeded)
    61       UNSOLVED = 1
    62     };
    63 
    64     ///Direction of the optimization
    65     enum Sense {
    66       /// Minimization
    67       MIN,
    68       /// Maximization
    69       MAX
    70     };
    71 
    72     ///The floating point type used by the solver
    73     typedef double Value;
    74     ///The infinity constant
    75     static const Value INF;
    76     ///The not a number constant
    77     static const Value NaN;
    78 
    79     friend class Col;
    80     friend class ColIt;
    81     friend class Row;
    82     friend class RowIt;
    83 
    84     ///Refer to a column of the LP.
    85 
    86     ///This type is used to refer to a column of the LP.
    87     ///
    88     ///Its value remains valid and correct even after the addition or erase of
    89     ///other columns.
    90     ///
    91     ///\note This class is similar to other Item types in LEMON, like
    92     ///Node and Arc types in digraph.
    93     class Col {
    94       friend class LpBase;
    95     protected:
    96       int _id;
    97       explicit Col(int id) : _id(id) {}
    98     public:
    99       typedef Value ExprValue;
   100       typedef True LpCol;
   101       /// Default constructor
   102       
   103       /// \warning The default constructor sets the Col to an
   104       /// undefined value.
   105       Col() {}
   106       /// Invalid constructor \& conversion.
   107       
   108       /// This constructor initializes the Col to be invalid.
   109       /// \sa Invalid for more details.      
   110       Col(const Invalid&) : _id(-1) {}
   111       /// Equality operator
   112 
   113       /// Two \ref Col "Col"s are equal if and only if they point to
   114       /// the same LP column or both are invalid.
   115       bool operator==(Col c) const  {return _id == c._id;}
   116       /// Inequality operator
   117 
   118       /// \sa operator==(Col c)
   119       ///
   120       bool operator!=(Col c) const  {return _id != c._id;}
   121       /// Artificial ordering operator.
   122 
   123       /// To allow the use of this object in std::map or similar
   124       /// associative container we require this.
   125       ///
   126       /// \note This operator only have to define some strict ordering of
   127       /// the items; this order has nothing to do with the iteration
   128       /// ordering of the items.
   129       bool operator<(Col c) const  {return _id < c._id;}
   130     };
   131 
   132     ///Iterator for iterate over the columns of an LP problem
   133 
   134     /// Its usage is quite simple, for example you can count the number
   135     /// of columns in an LP \c lp:
   136     ///\code
   137     /// int count=0;
   138     /// for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
   139     ///\endcode
   140     class ColIt : public Col {
   141       const LpBase *_solver;
   142     public:
   143       /// Default constructor
   144       
   145       /// \warning The default constructor sets the iterator
   146       /// to an undefined value.
   147       ColIt() {}
   148       /// Sets the iterator to the first Col
   149       
   150       /// Sets the iterator to the first Col.
   151       ///
   152       ColIt(const LpBase &solver) : _solver(&solver)
   153       {
   154         _solver->cols.firstItem(_id);
   155       }
   156       /// Invalid constructor \& conversion
   157       
   158       /// Initialize the iterator to be invalid.
   159       /// \sa Invalid for more details.
   160       ColIt(const Invalid&) : Col(INVALID) {}
   161       /// Next column
   162       
   163       /// Assign the iterator to the next column.
   164       ///
   165       ColIt &operator++()
   166       {
   167         _solver->cols.nextItem(_id);
   168         return *this;
   169       }
   170     };
   171 
   172     /// \brief Returns the ID of the column.
   173     static int id(const Col& col) { return col._id; }
   174     /// \brief Returns the column with the given ID.
   175     ///
   176     /// \pre The argument should be a valid column ID in the LP problem.
   177     static Col colFromId(int id) { return Col(id); }
   178 
   179     ///Refer to a row of the LP.
   180 
   181     ///This type is used to refer to a row of the LP.
   182     ///
   183     ///Its value remains valid and correct even after the addition or erase of
   184     ///other rows.
   185     ///
   186     ///\note This class is similar to other Item types in LEMON, like
   187     ///Node and Arc types in digraph.
   188     class Row {
   189       friend class LpBase;
   190     protected:
   191       int _id;
   192       explicit Row(int id) : _id(id) {}
   193     public:
   194       typedef Value ExprValue;
   195       typedef True LpRow;
   196       /// Default constructor
   197       
   198       /// \warning The default constructor sets the Row to an
   199       /// undefined value.
   200       Row() {}
   201       /// Invalid constructor \& conversion.
   202       
   203       /// This constructor initializes the Row to be invalid.
   204       /// \sa Invalid for more details.      
   205       Row(const Invalid&) : _id(-1) {}
   206       /// Equality operator
   207 
   208       /// Two \ref Row "Row"s are equal if and only if they point to
   209       /// the same LP row or both are invalid.
   210       bool operator==(Row r) const  {return _id == r._id;}
   211       /// Inequality operator
   212       
   213       /// \sa operator==(Row r)
   214       ///
   215       bool operator!=(Row r) const  {return _id != r._id;}
   216       /// Artificial ordering operator.
   217 
   218       /// To allow the use of this object in std::map or similar
   219       /// associative container we require this.
   220       ///
   221       /// \note This operator only have to define some strict ordering of
   222       /// the items; this order has nothing to do with the iteration
   223       /// ordering of the items.
   224       bool operator<(Row r) const  {return _id < r._id;}
   225     };
   226 
   227     ///Iterator for iterate over the rows of an LP problem
   228 
   229     /// Its usage is quite simple, for example you can count the number
   230     /// of rows in an LP \c lp:
   231     ///\code
   232     /// int count=0;
   233     /// for (LpBase::RowIt c(lp); c!=INVALID; ++c) ++count;
   234     ///\endcode
   235     class RowIt : public Row {
   236       const LpBase *_solver;
   237     public:
   238       /// Default constructor
   239       
   240       /// \warning The default constructor sets the iterator
   241       /// to an undefined value.
   242       RowIt() {}
   243       /// Sets the iterator to the first Row
   244       
   245       /// Sets the iterator to the first Row.
   246       ///
   247       RowIt(const LpBase &solver) : _solver(&solver)
   248       {
   249         _solver->rows.firstItem(_id);
   250       }
   251       /// Invalid constructor \& conversion
   252       
   253       /// Initialize the iterator to be invalid.
   254       /// \sa Invalid for more details.
   255       RowIt(const Invalid&) : Row(INVALID) {}
   256       /// Next row
   257       
   258       /// Assign the iterator to the next row.
   259       ///
   260       RowIt &operator++()
   261       {
   262         _solver->rows.nextItem(_id);
   263         return *this;
   264       }
   265     };
   266 
   267     /// \brief Returns the ID of the row.
   268     static int id(const Row& row) { return row._id; }
   269     /// \brief Returns the row with the given ID.
   270     ///
   271     /// \pre The argument should be a valid row ID in the LP problem.
   272     static Row rowFromId(int id) { return Row(id); }
   273 
   274   public:
   275 
   276     ///Linear expression of variables and a constant component
   277 
   278     ///This data structure stores a linear expression of the variables
   279     ///(\ref Col "Col"s) and also has a constant component.
   280     ///
   281     ///There are several ways to access and modify the contents of this
   282     ///container.
   283     ///\code
   284     ///e[v]=5;
   285     ///e[v]+=12;
   286     ///e.erase(v);
   287     ///\endcode
   288     ///or you can also iterate through its elements.
   289     ///\code
   290     ///double s=0;
   291     ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
   292     ///  s+=*i * primal(i);
   293     ///\endcode
   294     ///(This code computes the primal value of the expression).
   295     ///- Numbers (<tt>double</tt>'s)
   296     ///and variables (\ref Col "Col"s) directly convert to an
   297     ///\ref Expr and the usual linear operations are defined, so
   298     ///\code
   299     ///v+w
   300     ///2*v-3.12*(v-w/2)+2
   301     ///v*2.1+(3*v+(v*12+w+6)*3)/2
   302     ///\endcode
   303     ///are valid expressions.
   304     ///The usual assignment operations are also defined.
   305     ///\code
   306     ///e=v+w;
   307     ///e+=2*v-3.12*(v-w/2)+2;
   308     ///e*=3.4;
   309     ///e/=5;
   310     ///\endcode
   311     ///- The constant member can be set and read by dereference
   312     ///  operator (unary *)
   313     ///
   314     ///\code
   315     ///*e=12;
   316     ///double c=*e;
   317     ///\endcode
   318     ///
   319     ///\sa Constr
   320     class Expr {
   321       friend class LpBase;
   322     public:
   323       /// The key type of the expression
   324       typedef LpBase::Col Key;
   325       /// The value type of the expression
   326       typedef LpBase::Value Value;
   327 
   328     protected:
   329       Value const_comp;
   330       std::map<int, Value> comps;
   331 
   332     public:
   333       typedef True SolverExpr;
   334       /// Default constructor
   335       
   336       /// Construct an empty expression, the coefficients and
   337       /// the constant component are initialized to zero.
   338       Expr() : const_comp(0) {}
   339       /// Construct an expression from a column
   340 
   341       /// Construct an expression, which has a term with \c c variable
   342       /// and 1.0 coefficient.
   343       Expr(const Col &c) : const_comp(0) {
   344         typedef std::map<int, Value>::value_type pair_type;
   345         comps.insert(pair_type(id(c), 1));
   346       }
   347       /// Construct an expression from a constant
   348 
   349       /// Construct an expression, which's constant component is \c v.
   350       ///
   351       Expr(const Value &v) : const_comp(v) {}
   352       /// Returns the coefficient of the column
   353       Value operator[](const Col& c) const {
   354         std::map<int, Value>::const_iterator it=comps.find(id(c));
   355         if (it != comps.end()) {
   356           return it->second;
   357         } else {
   358           return 0;
   359         }
   360       }
   361       /// Returns the coefficient of the column
   362       Value& operator[](const Col& c) {
   363         return comps[id(c)];
   364       }
   365       /// Sets the coefficient of the column
   366       void set(const Col &c, const Value &v) {
   367         if (v != 0.0) {
   368           typedef std::map<int, Value>::value_type pair_type;
   369           comps.insert(pair_type(id(c), v));
   370         } else {
   371           comps.erase(id(c));
   372         }
   373       }
   374       /// Returns the constant component of the expression
   375       Value& operator*() { return const_comp; }
   376       /// Returns the constant component of the expression
   377       const Value& operator*() const { return const_comp; }
   378       /// \brief Removes the coefficients which's absolute value does
   379       /// not exceed \c epsilon. It also sets to zero the constant
   380       /// component, if it does not exceed epsilon in absolute value.
   381       void simplify(Value epsilon = 0.0) {
   382         std::map<int, Value>::iterator it=comps.begin();
   383         while (it != comps.end()) {
   384           std::map<int, Value>::iterator jt=it;
   385           ++jt;
   386           if (std::fabs((*it).second) <= epsilon) comps.erase(it);
   387           it=jt;
   388         }
   389         if (std::fabs(const_comp) <= epsilon) const_comp = 0;
   390       }
   391 
   392       void simplify(Value epsilon = 0.0) const {
   393         const_cast<Expr*>(this)->simplify(epsilon);
   394       }
   395 
   396       ///Sets all coefficients and the constant component to 0.
   397       void clear() {
   398         comps.clear();
   399         const_comp=0;
   400       }
   401 
   402       ///Compound assignment
   403       Expr &operator+=(const Expr &e) {
   404         for (std::map<int, Value>::const_iterator it=e.comps.begin();
   405              it!=e.comps.end(); ++it)
   406           comps[it->first]+=it->second;
   407         const_comp+=e.const_comp;
   408         return *this;
   409       }
   410       ///Compound assignment
   411       Expr &operator-=(const Expr &e) {
   412         for (std::map<int, Value>::const_iterator it=e.comps.begin();
   413              it!=e.comps.end(); ++it)
   414           comps[it->first]-=it->second;
   415         const_comp-=e.const_comp;
   416         return *this;
   417       }
   418       ///Multiply with a constant
   419       Expr &operator*=(const Value &v) {
   420         for (std::map<int, Value>::iterator it=comps.begin();
   421              it!=comps.end(); ++it)
   422           it->second*=v;
   423         const_comp*=v;
   424         return *this;
   425       }
   426       ///Division with a constant
   427       Expr &operator/=(const Value &c) {
   428         for (std::map<int, Value>::iterator it=comps.begin();
   429              it!=comps.end(); ++it)
   430           it->second/=c;
   431         const_comp/=c;
   432         return *this;
   433       }
   434 
   435       ///Iterator over the expression
   436       
   437       ///The iterator iterates over the terms of the expression. 
   438       /// 
   439       ///\code
   440       ///double s=0;
   441       ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i)
   442       ///  s+= *i * primal(i);
   443       ///\endcode
   444       class CoeffIt {
   445       private:
   446 
   447         std::map<int, Value>::iterator _it, _end;
   448 
   449       public:
   450 
   451         /// Sets the iterator to the first term
   452         
   453         /// Sets the iterator to the first term of the expression.
   454         ///
   455         CoeffIt(Expr& e)
   456           : _it(e.comps.begin()), _end(e.comps.end()){}
   457 
   458         /// Convert the iterator to the column of the term
   459         operator Col() const {
   460           return colFromId(_it->first);
   461         }
   462 
   463         /// Returns the coefficient of the term
   464         Value& operator*() { return _it->second; }
   465 
   466         /// Returns the coefficient of the term
   467         const Value& operator*() const { return _it->second; }
   468         /// Next term
   469         
   470         /// Assign the iterator to the next term.
   471         ///
   472         CoeffIt& operator++() { ++_it; return *this; }
   473 
   474         /// Equality operator
   475         bool operator==(Invalid) const { return _it == _end; }
   476         /// Inequality operator
   477         bool operator!=(Invalid) const { return _it != _end; }
   478       };
   479 
   480       /// Const iterator over the expression
   481       
   482       ///The iterator iterates over the terms of the expression. 
   483       /// 
   484       ///\code
   485       ///double s=0;
   486       ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
   487       ///  s+=*i * primal(i);
   488       ///\endcode
   489       class ConstCoeffIt {
   490       private:
   491 
   492         std::map<int, Value>::const_iterator _it, _end;
   493 
   494       public:
   495 
   496         /// Sets the iterator to the first term
   497         
   498         /// Sets the iterator to the first term of the expression.
   499         ///
   500         ConstCoeffIt(const Expr& e)
   501           : _it(e.comps.begin()), _end(e.comps.end()){}
   502 
   503         /// Convert the iterator to the column of the term
   504         operator Col() const {
   505           return colFromId(_it->first);
   506         }
   507 
   508         /// Returns the coefficient of the term
   509         const Value& operator*() const { return _it->second; }
   510 
   511         /// Next term
   512         
   513         /// Assign the iterator to the next term.
   514         ///
   515         ConstCoeffIt& operator++() { ++_it; return *this; }
   516 
   517         /// Equality operator
   518         bool operator==(Invalid) const { return _it == _end; }
   519         /// Inequality operator
   520         bool operator!=(Invalid) const { return _it != _end; }
   521       };
   522 
   523     };
   524 
   525     ///Linear constraint
   526 
   527     ///This data stucture represents a linear constraint in the LP.
   528     ///Basically it is a linear expression with a lower or an upper bound
   529     ///(or both). These parts of the constraint can be obtained by the member
   530     ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
   531     ///respectively.
   532     ///There are two ways to construct a constraint.
   533     ///- You can set the linear expression and the bounds directly
   534     ///  by the functions above.
   535     ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
   536     ///  are defined between expressions, or even between constraints whenever
   537     ///  it makes sense. Therefore if \c e and \c f are linear expressions and
   538     ///  \c s and \c t are numbers, then the followings are valid expressions
   539     ///  and thus they can be used directly e.g. in \ref addRow() whenever
   540     ///  it makes sense.
   541     ///\code
   542     ///  e<=s
   543     ///  e<=f
   544     ///  e==f
   545     ///  s<=e<=t
   546     ///  e>=t
   547     ///\endcode
   548     ///\warning The validity of a constraint is checked only at run
   549     ///time, so e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will
   550     ///compile, but will fail an assertion.
   551     class Constr
   552     {
   553     public:
   554       typedef LpBase::Expr Expr;
   555       typedef Expr::Key Key;
   556       typedef Expr::Value Value;
   557 
   558     protected:
   559       Expr _expr;
   560       Value _lb,_ub;
   561     public:
   562       ///\e
   563       Constr() : _expr(), _lb(NaN), _ub(NaN) {}
   564       ///\e
   565       Constr(Value lb, const Expr &e, Value ub) :
   566         _expr(e), _lb(lb), _ub(ub) {}
   567       Constr(const Expr &e) :
   568         _expr(e), _lb(NaN), _ub(NaN) {}
   569       ///\e
   570       void clear()
   571       {
   572         _expr.clear();
   573         _lb=_ub=NaN;
   574       }
   575 
   576       ///Reference to the linear expression
   577       Expr &expr() { return _expr; }
   578       ///Cont reference to the linear expression
   579       const Expr &expr() const { return _expr; }
   580       ///Reference to the lower bound.
   581 
   582       ///\return
   583       ///- \ref INF "INF": the constraint is lower unbounded.
   584       ///- \ref NaN "NaN": lower bound has not been set.
   585       ///- finite number: the lower bound
   586       Value &lowerBound() { return _lb; }
   587       ///The const version of \ref lowerBound()
   588       const Value &lowerBound() const { return _lb; }
   589       ///Reference to the upper bound.
   590 
   591       ///\return
   592       ///- \ref INF "INF": the constraint is upper unbounded.
   593       ///- \ref NaN "NaN": upper bound has not been set.
   594       ///- finite number: the upper bound
   595       Value &upperBound() { return _ub; }
   596       ///The const version of \ref upperBound()
   597       const Value &upperBound() const { return _ub; }
   598       ///Is the constraint lower bounded?
   599       bool lowerBounded() const {
   600         return _lb != -INF && !isNaN(_lb);
   601       }
   602       ///Is the constraint upper bounded?
   603       bool upperBounded() const {
   604         return _ub != INF && !isNaN(_ub);
   605       }
   606 
   607     };
   608 
   609     ///Linear expression of rows
   610 
   611     ///This data structure represents a column of the matrix,
   612     ///thas is it strores a linear expression of the dual variables
   613     ///(\ref Row "Row"s).
   614     ///
   615     ///There are several ways to access and modify the contents of this
   616     ///container.
   617     ///\code
   618     ///e[v]=5;
   619     ///e[v]+=12;
   620     ///e.erase(v);
   621     ///\endcode
   622     ///or you can also iterate through its elements.
   623     ///\code
   624     ///double s=0;
   625     ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
   626     ///  s+=*i;
   627     ///\endcode
   628     ///(This code computes the sum of all coefficients).
   629     ///- Numbers (<tt>double</tt>'s)
   630     ///and variables (\ref Row "Row"s) directly convert to an
   631     ///\ref DualExpr and the usual linear operations are defined, so
   632     ///\code
   633     ///v+w
   634     ///2*v-3.12*(v-w/2)
   635     ///v*2.1+(3*v+(v*12+w)*3)/2
   636     ///\endcode
   637     ///are valid \ref DualExpr dual expressions.
   638     ///The usual assignment operations are also defined.
   639     ///\code
   640     ///e=v+w;
   641     ///e+=2*v-3.12*(v-w/2);
   642     ///e*=3.4;
   643     ///e/=5;
   644     ///\endcode
   645     ///
   646     ///\sa Expr
   647     class DualExpr {
   648       friend class LpBase;
   649     public:
   650       /// The key type of the expression
   651       typedef LpBase::Row Key;
   652       /// The value type of the expression
   653       typedef LpBase::Value Value;
   654 
   655     protected:
   656       std::map<int, Value> comps;
   657 
   658     public:
   659       typedef True SolverExpr;
   660       /// Default constructor
   661       
   662       /// Construct an empty expression, the coefficients are
   663       /// initialized to zero.
   664       DualExpr() {}
   665       /// Construct an expression from a row
   666 
   667       /// Construct an expression, which has a term with \c r dual
   668       /// variable and 1.0 coefficient.
   669       DualExpr(const Row &r) {
   670         typedef std::map<int, Value>::value_type pair_type;
   671         comps.insert(pair_type(id(r), 1));
   672       }
   673       /// Returns the coefficient of the row
   674       Value operator[](const Row& r) const {
   675         std::map<int, Value>::const_iterator it = comps.find(id(r));
   676         if (it != comps.end()) {
   677           return it->second;
   678         } else {
   679           return 0;
   680         }
   681       }
   682       /// Returns the coefficient of the row
   683       Value& operator[](const Row& r) {
   684         return comps[id(r)];
   685       }
   686       /// Sets the coefficient of the row
   687       void set(const Row &r, const Value &v) {
   688         if (v != 0.0) {
   689           typedef std::map<int, Value>::value_type pair_type;
   690           comps.insert(pair_type(id(r), v));
   691         } else {
   692           comps.erase(id(r));
   693         }
   694       }
   695       /// \brief Removes the coefficients which's absolute value does
   696       /// not exceed \c epsilon. 
   697       void simplify(Value epsilon = 0.0) {
   698         std::map<int, Value>::iterator it=comps.begin();
   699         while (it != comps.end()) {
   700           std::map<int, Value>::iterator jt=it;
   701           ++jt;
   702           if (std::fabs((*it).second) <= epsilon) comps.erase(it);
   703           it=jt;
   704         }
   705       }
   706 
   707       void simplify(Value epsilon = 0.0) const {
   708         const_cast<DualExpr*>(this)->simplify(epsilon);
   709       }
   710 
   711       ///Sets all coefficients to 0.
   712       void clear() {
   713         comps.clear();
   714       }
   715       ///Compound assignment
   716       DualExpr &operator+=(const DualExpr &e) {
   717         for (std::map<int, Value>::const_iterator it=e.comps.begin();
   718              it!=e.comps.end(); ++it)
   719           comps[it->first]+=it->second;
   720         return *this;
   721       }
   722       ///Compound assignment
   723       DualExpr &operator-=(const DualExpr &e) {
   724         for (std::map<int, Value>::const_iterator it=e.comps.begin();
   725              it!=e.comps.end(); ++it)
   726           comps[it->first]-=it->second;
   727         return *this;
   728       }
   729       ///Multiply with a constant
   730       DualExpr &operator*=(const Value &v) {
   731         for (std::map<int, Value>::iterator it=comps.begin();
   732              it!=comps.end(); ++it)
   733           it->second*=v;
   734         return *this;
   735       }
   736       ///Division with a constant
   737       DualExpr &operator/=(const Value &v) {
   738         for (std::map<int, Value>::iterator it=comps.begin();
   739              it!=comps.end(); ++it)
   740           it->second/=v;
   741         return *this;
   742       }
   743 
   744       ///Iterator over the expression
   745       
   746       ///The iterator iterates over the terms of the expression. 
   747       /// 
   748       ///\code
   749       ///double s=0;
   750       ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i)
   751       ///  s+= *i * dual(i);
   752       ///\endcode
   753       class CoeffIt {
   754       private:
   755 
   756         std::map<int, Value>::iterator _it, _end;
   757 
   758       public:
   759 
   760         /// Sets the iterator to the first term
   761         
   762         /// Sets the iterator to the first term of the expression.
   763         ///
   764         CoeffIt(DualExpr& e)
   765           : _it(e.comps.begin()), _end(e.comps.end()){}
   766 
   767         /// Convert the iterator to the row of the term
   768         operator Row() const {
   769           return rowFromId(_it->first);
   770         }
   771 
   772         /// Returns the coefficient of the term
   773         Value& operator*() { return _it->second; }
   774 
   775         /// Returns the coefficient of the term
   776         const Value& operator*() const { return _it->second; }
   777 
   778         /// Next term
   779         
   780         /// Assign the iterator to the next term.
   781         ///
   782         CoeffIt& operator++() { ++_it; return *this; }
   783 
   784         /// Equality operator
   785         bool operator==(Invalid) const { return _it == _end; }
   786         /// Inequality operator
   787         bool operator!=(Invalid) const { return _it != _end; }
   788       };
   789 
   790       ///Iterator over the expression
   791       
   792       ///The iterator iterates over the terms of the expression. 
   793       /// 
   794       ///\code
   795       ///double s=0;
   796       ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
   797       ///  s+= *i * dual(i);
   798       ///\endcode
   799       class ConstCoeffIt {
   800       private:
   801 
   802         std::map<int, Value>::const_iterator _it, _end;
   803 
   804       public:
   805 
   806         /// Sets the iterator to the first term
   807         
   808         /// Sets the iterator to the first term of the expression.
   809         ///
   810         ConstCoeffIt(const DualExpr& e)
   811           : _it(e.comps.begin()), _end(e.comps.end()){}
   812 
   813         /// Convert the iterator to the row of the term
   814         operator Row() const {
   815           return rowFromId(_it->first);
   816         }
   817 
   818         /// Returns the coefficient of the term
   819         const Value& operator*() const { return _it->second; }
   820 
   821         /// Next term
   822         
   823         /// Assign the iterator to the next term.
   824         ///
   825         ConstCoeffIt& operator++() { ++_it; return *this; }
   826 
   827         /// Equality operator
   828         bool operator==(Invalid) const { return _it == _end; }
   829         /// Inequality operator
   830         bool operator!=(Invalid) const { return _it != _end; }
   831       };
   832     };
   833 
   834 
   835   protected:
   836 
   837     class InsertIterator {
   838     private:
   839 
   840       std::map<int, Value>& _host;
   841       const _solver_bits::VarIndex& _index;
   842 
   843     public:
   844 
   845       typedef std::output_iterator_tag iterator_category;
   846       typedef void difference_type;
   847       typedef void value_type;
   848       typedef void reference;
   849       typedef void pointer;
   850 
   851       InsertIterator(std::map<int, Value>& host,
   852                    const _solver_bits::VarIndex& index)
   853         : _host(host), _index(index) {}
   854 
   855       InsertIterator& operator=(const std::pair<int, Value>& value) {
   856         typedef std::map<int, Value>::value_type pair_type;
   857         _host.insert(pair_type(_index[value.first], value.second));
   858         return *this;
   859       }
   860 
   861       InsertIterator& operator*() { return *this; }
   862       InsertIterator& operator++() { return *this; }
   863       InsertIterator operator++(int) { return *this; }
   864 
   865     };
   866 
   867     class ExprIterator {
   868     private:
   869       std::map<int, Value>::const_iterator _host_it;
   870       const _solver_bits::VarIndex& _index;
   871     public:
   872 
   873       typedef std::bidirectional_iterator_tag iterator_category;
   874       typedef std::ptrdiff_t difference_type;
   875       typedef const std::pair<int, Value> value_type;
   876       typedef value_type reference;
   877 
   878       class pointer {
   879       public:
   880         pointer(value_type& _value) : value(_value) {}
   881         value_type* operator->() { return &value; }
   882       private:
   883         value_type value;
   884       };
   885 
   886       ExprIterator(const std::map<int, Value>::const_iterator& host_it,
   887                    const _solver_bits::VarIndex& index)
   888         : _host_it(host_it), _index(index) {}
   889 
   890       reference operator*() {
   891         return std::make_pair(_index(_host_it->first), _host_it->second);
   892       }
   893 
   894       pointer operator->() {
   895         return pointer(operator*());
   896       }
   897 
   898       ExprIterator& operator++() { ++_host_it; return *this; }
   899       ExprIterator operator++(int) {
   900         ExprIterator tmp(*this); ++_host_it; return tmp;
   901       }
   902 
   903       ExprIterator& operator--() { --_host_it; return *this; }
   904       ExprIterator operator--(int) {
   905         ExprIterator tmp(*this); --_host_it; return tmp;
   906       }
   907 
   908       bool operator==(const ExprIterator& it) const {
   909         return _host_it == it._host_it;
   910       }
   911 
   912       bool operator!=(const ExprIterator& it) const {
   913         return _host_it != it._host_it;
   914       }
   915 
   916     };
   917 
   918   protected:
   919 
   920     //Abstract virtual functions
   921 
   922     virtual int _addColId(int col) { return cols.addIndex(col); }
   923     virtual int _addRowId(int row) { return rows.addIndex(row); }
   924 
   925     virtual void _eraseColId(int col) { cols.eraseIndex(col); }
   926     virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
   927 
   928     virtual int _addCol() = 0;
   929     virtual int _addRow() = 0;
   930 
   931     virtual void _eraseCol(int col) = 0;
   932     virtual void _eraseRow(int row) = 0;
   933 
   934     virtual void _getColName(int col, std::string& name) const = 0;
   935     virtual void _setColName(int col, const std::string& name) = 0;
   936     virtual int _colByName(const std::string& name) const = 0;
   937 
   938     virtual void _getRowName(int row, std::string& name) const = 0;
   939     virtual void _setRowName(int row, const std::string& name) = 0;
   940     virtual int _rowByName(const std::string& name) const = 0;
   941 
   942     virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
   943     virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
   944 
   945     virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
   946     virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
   947 
   948     virtual void _setCoeff(int row, int col, Value value) = 0;
   949     virtual Value _getCoeff(int row, int col) const = 0;
   950 
   951     virtual void _setColLowerBound(int i, Value value) = 0;
   952     virtual Value _getColLowerBound(int i) const = 0;
   953 
   954     virtual void _setColUpperBound(int i, Value value) = 0;
   955     virtual Value _getColUpperBound(int i) const = 0;
   956 
   957     virtual void _setRowLowerBound(int i, Value value) = 0;
   958     virtual Value _getRowLowerBound(int i) const = 0;
   959 
   960     virtual void _setRowUpperBound(int i, Value value) = 0;
   961     virtual Value _getRowUpperBound(int i) const = 0;
   962 
   963     virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
   964     virtual void _getObjCoeffs(InsertIterator b) const = 0;
   965 
   966     virtual void _setObjCoeff(int i, Value obj_coef) = 0;
   967     virtual Value _getObjCoeff(int i) const = 0;
   968 
   969     virtual void _setSense(Sense) = 0;
   970     virtual Sense _getSense() const = 0;
   971 
   972     virtual void _clear() = 0;
   973 
   974     virtual const char* _solverName() const = 0;
   975 
   976     //Own protected stuff
   977 
   978     //Constant component of the objective function
   979     Value obj_const_comp;
   980 
   981     LpBase() : rows(), cols(), obj_const_comp(0) {}
   982 
   983   public:
   984 
   985     /// Virtual destructor
   986     virtual ~LpBase() {}
   987 
   988     ///Gives back the name of the solver.
   989     const char* solverName() const {return _solverName();}
   990 
   991     ///\name Build up and modify the LP
   992 
   993     ///@{
   994 
   995     ///Add a new empty column (i.e a new variable) to the LP
   996     Col addCol() { Col c; c._id = _addColId(_addCol()); return c;}
   997 
   998     ///\brief Adds several new columns (i.e variables) at once
   999     ///
  1000     ///This magic function takes a container as its argument and fills
  1001     ///its elements with new columns (i.e. variables)
  1002     ///\param t can be
  1003     ///- a standard STL compatible iterable container with
  1004     ///\ref Col as its \c values_type like
  1005     ///\code
  1006     ///std::vector<LpBase::Col>
  1007     ///std::list<LpBase::Col>
  1008     ///\endcode
  1009     ///- a standard STL compatible iterable container with
  1010     ///\ref Col as its \c mapped_type like
  1011     ///\code
  1012     ///std::map<AnyType,LpBase::Col>
  1013     ///\endcode
  1014     ///- an iterable lemon \ref concepts::WriteMap "write map" like
  1015     ///\code
  1016     ///ListGraph::NodeMap<LpBase::Col>
  1017     ///ListGraph::ArcMap<LpBase::Col>
  1018     ///\endcode
  1019     ///\return The number of the created column.
  1020 #ifdef DOXYGEN
  1021     template<class T>
  1022     int addColSet(T &t) { return 0;}
  1023 #else
  1024     template<class T>
  1025     typename enable_if<typename T::value_type::LpCol,int>::type
  1026     addColSet(T &t,dummy<0> = 0) {
  1027       int s=0;
  1028       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
  1029       return s;
  1030     }
  1031     template<class T>
  1032     typename enable_if<typename T::value_type::second_type::LpCol,
  1033                        int>::type
  1034     addColSet(T &t,dummy<1> = 1) {
  1035       int s=0;
  1036       for(typename T::iterator i=t.begin();i!=t.end();++i) {
  1037         i->second=addCol();
  1038         s++;
  1039       }
  1040       return s;
  1041     }
  1042     template<class T>
  1043     typename enable_if<typename T::MapIt::Value::LpCol,
  1044                        int>::type
  1045     addColSet(T &t,dummy<2> = 2) {
  1046       int s=0;
  1047       for(typename T::MapIt i(t); i!=INVALID; ++i)
  1048         {
  1049           i.set(addCol());
  1050           s++;
  1051         }
  1052       return s;
  1053     }
  1054 #endif
  1055 
  1056     ///Set a column (i.e a dual constraint) of the LP
  1057 
  1058     ///\param c is the column to be modified
  1059     ///\param e is a dual linear expression (see \ref DualExpr)
  1060     ///a better one.
  1061     void col(Col c, const DualExpr &e) {
  1062       e.simplify();
  1063       _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), rows),
  1064                     ExprIterator(e.comps.end(), rows));
  1065     }
  1066 
  1067     ///Get a column (i.e a dual constraint) of the LP
  1068 
  1069     ///\param c is the column to get
  1070     ///\return the dual expression associated to the column
  1071     DualExpr col(Col c) const {
  1072       DualExpr e;
  1073       _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows));
  1074       return e;
  1075     }
  1076 
  1077     ///Add a new column to the LP
  1078 
  1079     ///\param e is a dual linear expression (see \ref DualExpr)
  1080     ///\param o is the corresponding component of the objective
  1081     ///function. It is 0 by default.
  1082     ///\return The created column.
  1083     Col addCol(const DualExpr &e, Value o = 0) {
  1084       Col c=addCol();
  1085       col(c,e);
  1086       objCoeff(c,o);
  1087       return c;
  1088     }
  1089 
  1090     ///Add a new empty row (i.e a new constraint) to the LP
  1091 
  1092     ///This function adds a new empty row (i.e a new constraint) to the LP.
  1093     ///\return The created row
  1094     Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;}
  1095 
  1096     ///\brief Add several new rows (i.e constraints) at once
  1097     ///
  1098     ///This magic function takes a container as its argument and fills
  1099     ///its elements with new row (i.e. variables)
  1100     ///\param t can be
  1101     ///- a standard STL compatible iterable container with
  1102     ///\ref Row as its \c values_type like
  1103     ///\code
  1104     ///std::vector<LpBase::Row>
  1105     ///std::list<LpBase::Row>
  1106     ///\endcode
  1107     ///- a standard STL compatible iterable container with
  1108     ///\ref Row as its \c mapped_type like
  1109     ///\code
  1110     ///std::map<AnyType,LpBase::Row>
  1111     ///\endcode
  1112     ///- an iterable lemon \ref concepts::WriteMap "write map" like
  1113     ///\code
  1114     ///ListGraph::NodeMap<LpBase::Row>
  1115     ///ListGraph::ArcMap<LpBase::Row>
  1116     ///\endcode
  1117     ///\return The number of rows created.
  1118 #ifdef DOXYGEN
  1119     template<class T>
  1120     int addRowSet(T &t) { return 0;}
  1121 #else
  1122     template<class T>
  1123     typename enable_if<typename T::value_type::LpRow,int>::type
  1124     addRowSet(T &t, dummy<0> = 0) {
  1125       int s=0;
  1126       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
  1127       return s;
  1128     }
  1129     template<class T>
  1130     typename enable_if<typename T::value_type::second_type::LpRow, int>::type
  1131     addRowSet(T &t, dummy<1> = 1) {
  1132       int s=0;
  1133       for(typename T::iterator i=t.begin();i!=t.end();++i) {
  1134         i->second=addRow();
  1135         s++;
  1136       }
  1137       return s;
  1138     }
  1139     template<class T>
  1140     typename enable_if<typename T::MapIt::Value::LpRow, int>::type
  1141     addRowSet(T &t, dummy<2> = 2) {
  1142       int s=0;
  1143       for(typename T::MapIt i(t); i!=INVALID; ++i)
  1144         {
  1145           i.set(addRow());
  1146           s++;
  1147         }
  1148       return s;
  1149     }
  1150 #endif
  1151 
  1152     ///Set a row (i.e a constraint) of the LP
  1153 
  1154     ///\param r is the row to be modified
  1155     ///\param l is lower bound (-\ref INF means no bound)
  1156     ///\param e is a linear expression (see \ref Expr)
  1157     ///\param u is the upper bound (\ref INF means no bound)
  1158     void row(Row r, Value l, const Expr &e, Value u) {
  1159       e.simplify();
  1160       _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
  1161                     ExprIterator(e.comps.end(), cols));
  1162       _setRowLowerBound(rows(id(r)),l - *e);
  1163       _setRowUpperBound(rows(id(r)),u - *e);
  1164     }
  1165 
  1166     ///Set a row (i.e a constraint) of the LP
  1167 
  1168     ///\param r is the row to be modified
  1169     ///\param c is a linear expression (see \ref Constr)
  1170     void row(Row r, const Constr &c) {
  1171       row(r, c.lowerBounded()?c.lowerBound():-INF,
  1172           c.expr(), c.upperBounded()?c.upperBound():INF);
  1173     }
  1174 
  1175 
  1176     ///Get a row (i.e a constraint) of the LP
  1177 
  1178     ///\param r is the row to get
  1179     ///\return the expression associated to the row
  1180     Expr row(Row r) const {
  1181       Expr e;
  1182       _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
  1183       return e;
  1184     }
  1185 
  1186     ///Add a new row (i.e a new constraint) to the LP
  1187 
  1188     ///\param l is the lower bound (-\ref INF means no bound)
  1189     ///\param e is a linear expression (see \ref Expr)
  1190     ///\param u is the upper bound (\ref INF means no bound)
  1191     ///\return The created row.
  1192     Row addRow(Value l,const Expr &e, Value u) {
  1193       Row r=addRow();
  1194       row(r,l,e,u);
  1195       return r;
  1196     }
  1197 
  1198     ///Add a new row (i.e a new constraint) to the LP
  1199 
  1200     ///\param c is a linear expression (see \ref Constr)
  1201     ///\return The created row.
  1202     Row addRow(const Constr &c) {
  1203       Row r=addRow();
  1204       row(r,c);
  1205       return r;
  1206     }
  1207     ///Erase a column (i.e a variable) from the LP
  1208 
  1209     ///\param c is the column to be deleted
  1210     void erase(Col c) {
  1211       _eraseCol(cols(id(c)));
  1212       _eraseColId(cols(id(c)));
  1213     }
  1214     ///Erase a row (i.e a constraint) from the LP
  1215 
  1216     ///\param r is the row to be deleted
  1217     void erase(Row r) {
  1218       _eraseRow(rows(id(r)));
  1219       _eraseRowId(rows(id(r)));
  1220     }
  1221 
  1222     /// Get the name of a column
  1223 
  1224     ///\param c is the coresponding column
  1225     ///\return The name of the colunm
  1226     std::string colName(Col c) const {
  1227       std::string name;
  1228       _getColName(cols(id(c)), name);
  1229       return name;
  1230     }
  1231 
  1232     /// Set the name of a column
  1233 
  1234     ///\param c is the coresponding column
  1235     ///\param name The name to be given
  1236     void colName(Col c, const std::string& name) {
  1237       _setColName(cols(id(c)), name);
  1238     }
  1239 
  1240     /// Get the column by its name
  1241 
  1242     ///\param name The name of the column
  1243     ///\return the proper column or \c INVALID
  1244     Col colByName(const std::string& name) const {
  1245       int k = _colByName(name);
  1246       return k != -1 ? Col(cols[k]) : Col(INVALID);
  1247     }
  1248 
  1249     /// Get the name of a row
  1250 
  1251     ///\param r is the coresponding row
  1252     ///\return The name of the row
  1253     std::string rowName(Row r) const {
  1254       std::string name;
  1255       _getRowName(rows(id(r)), name);
  1256       return name;
  1257     }
  1258 
  1259     /// Set the name of a row
  1260 
  1261     ///\param r is the coresponding row
  1262     ///\param name The name to be given
  1263     void rowName(Row r, const std::string& name) {
  1264       _setRowName(rows(id(r)), name);
  1265     }
  1266 
  1267     /// Get the row by its name
  1268 
  1269     ///\param name The name of the row
  1270     ///\return the proper row or \c INVALID
  1271     Row rowByName(const std::string& name) const {
  1272       int k = _rowByName(name);
  1273       return k != -1 ? Row(rows[k]) : Row(INVALID);
  1274     }
  1275 
  1276     /// Set an element of the coefficient matrix of the LP
  1277 
  1278     ///\param r is the row of the element to be modified
  1279     ///\param c is the column of the element to be modified
  1280     ///\param val is the new value of the coefficient
  1281     void coeff(Row r, Col c, Value val) {
  1282       _setCoeff(rows(id(r)),cols(id(c)), val);
  1283     }
  1284 
  1285     /// Get an element of the coefficient matrix of the LP
  1286 
  1287     ///\param r is the row of the element
  1288     ///\param c is the column of the element
  1289     ///\return the corresponding coefficient
  1290     Value coeff(Row r, Col c) const {
  1291       return _getCoeff(rows(id(r)),cols(id(c)));
  1292     }
  1293 
  1294     /// Set the lower bound of a column (i.e a variable)
  1295 
  1296     /// The lower bound of a variable (column) has to be given by an
  1297     /// extended number of type Value, i.e. a finite number of type
  1298     /// Value or -\ref INF.
  1299     void colLowerBound(Col c, Value value) {
  1300       _setColLowerBound(cols(id(c)),value);
  1301     }
  1302 
  1303     /// Get the lower bound of a column (i.e a variable)
  1304 
  1305     /// This function returns the lower bound for column (variable) \c c
  1306     /// (this might be -\ref INF as well).
  1307     ///\return The lower bound for column \c c
  1308     Value colLowerBound(Col c) const {
  1309       return _getColLowerBound(cols(id(c)));
  1310     }
  1311 
  1312     ///\brief Set the lower bound of  several columns
  1313     ///(i.e variables) at once
  1314     ///
  1315     ///This magic function takes a container as its argument
  1316     ///and applies the function on all of its elements.
  1317     ///The lower bound of a variable (column) has to be given by an
  1318     ///extended number of type Value, i.e. a finite number of type
  1319     ///Value or -\ref INF.
  1320 #ifdef DOXYGEN
  1321     template<class T>
  1322     void colLowerBound(T &t, Value value) { return 0;}
  1323 #else
  1324     template<class T>
  1325     typename enable_if<typename T::value_type::LpCol,void>::type
  1326     colLowerBound(T &t, Value value,dummy<0> = 0) {
  1327       for(typename T::iterator i=t.begin();i!=t.end();++i) {
  1328         colLowerBound(*i, value);
  1329       }
  1330     }
  1331     template<class T>
  1332     typename enable_if<typename T::value_type::second_type::LpCol,
  1333                        void>::type
  1334     colLowerBound(T &t, Value value,dummy<1> = 1) {
  1335       for(typename T::iterator i=t.begin();i!=t.end();++i) {
  1336         colLowerBound(i->second, value);
  1337       }
  1338     }
  1339     template<class T>
  1340     typename enable_if<typename T::MapIt::Value::LpCol,
  1341                        void>::type
  1342     colLowerBound(T &t, Value value,dummy<2> = 2) {
  1343       for(typename T::MapIt i(t); i!=INVALID; ++i){
  1344         colLowerBound(*i, value);
  1345       }
  1346     }
  1347 #endif
  1348 
  1349     /// Set the upper bound of a column (i.e a variable)
  1350 
  1351     /// The upper bound of a variable (column) has to be given by an
  1352     /// extended number of type Value, i.e. a finite number of type
  1353     /// Value or \ref INF.
  1354     void colUpperBound(Col c, Value value) {
  1355       _setColUpperBound(cols(id(c)),value);
  1356     };
  1357 
  1358     /// Get the upper bound of a column (i.e a variable)
  1359 
  1360     /// This function returns the upper bound for column (variable) \c c
  1361     /// (this might be \ref INF as well).
  1362     /// \return The upper bound for column \c c
  1363     Value colUpperBound(Col c) const {
  1364       return _getColUpperBound(cols(id(c)));
  1365     }
  1366 
  1367     ///\brief Set the upper bound of  several columns
  1368     ///(i.e variables) at once
  1369     ///
  1370     ///This magic function takes a container as its argument
  1371     ///and applies the function on all of its elements.
  1372     ///The upper bound of a variable (column) has to be given by an
  1373     ///extended number of type Value, i.e. a finite number of type
  1374     ///Value or \ref INF.
  1375 #ifdef DOXYGEN
  1376     template<class T>
  1377     void colUpperBound(T &t, Value value) { return 0;}
  1378 #else
  1379     template<class T1>
  1380     typename enable_if<typename T1::value_type::LpCol,void>::type
  1381     colUpperBound(T1 &t, Value value,dummy<0> = 0) {
  1382       for(typename T1::iterator i=t.begin();i!=t.end();++i) {
  1383         colUpperBound(*i, value);
  1384       }
  1385     }
  1386     template<class T1>
  1387     typename enable_if<typename T1::value_type::second_type::LpCol,
  1388                        void>::type
  1389     colUpperBound(T1 &t, Value value,dummy<1> = 1) {
  1390       for(typename T1::iterator i=t.begin();i!=t.end();++i) {
  1391         colUpperBound(i->second, value);
  1392       }
  1393     }
  1394     template<class T1>
  1395     typename enable_if<typename T1::MapIt::Value::LpCol,
  1396                        void>::type
  1397     colUpperBound(T1 &t, Value value,dummy<2> = 2) {
  1398       for(typename T1::MapIt i(t); i!=INVALID; ++i){
  1399         colUpperBound(*i, value);
  1400       }
  1401     }
  1402 #endif
  1403 
  1404     /// Set the lower and the upper bounds of a column (i.e a variable)
  1405 
  1406     /// The lower and the upper bounds of
  1407     /// a variable (column) have to be given by an
  1408     /// extended number of type Value, i.e. a finite number of type
  1409     /// Value, -\ref INF or \ref INF.
  1410     void colBounds(Col c, Value lower, Value upper) {
  1411       _setColLowerBound(cols(id(c)),lower);
  1412       _setColUpperBound(cols(id(c)),upper);
  1413     }
  1414 
  1415     ///\brief Set the lower and the upper bound of several columns
  1416     ///(i.e variables) at once
  1417     ///
  1418     ///This magic function takes a container as its argument
  1419     ///and applies the function on all of its elements.
  1420     /// The lower and the upper bounds of
  1421     /// a variable (column) have to be given by an
  1422     /// extended number of type Value, i.e. a finite number of type
  1423     /// Value, -\ref INF or \ref INF.
  1424 #ifdef DOXYGEN
  1425     template<class T>
  1426     void colBounds(T &t, Value lower, Value upper) { return 0;}
  1427 #else
  1428     template<class T2>
  1429     typename enable_if<typename T2::value_type::LpCol,void>::type
  1430     colBounds(T2 &t, Value lower, Value upper,dummy<0> = 0) {
  1431       for(typename T2::iterator i=t.begin();i!=t.end();++i) {
  1432         colBounds(*i, lower, upper);
  1433       }
  1434     }
  1435     template<class T2>
  1436     typename enable_if<typename T2::value_type::second_type::LpCol, void>::type
  1437     colBounds(T2 &t, Value lower, Value upper,dummy<1> = 1) {
  1438       for(typename T2::iterator i=t.begin();i!=t.end();++i) {
  1439         colBounds(i->second, lower, upper);
  1440       }
  1441     }
  1442     template<class T2>
  1443     typename enable_if<typename T2::MapIt::Value::LpCol, void>::type
  1444     colBounds(T2 &t, Value lower, Value upper,dummy<2> = 2) {
  1445       for(typename T2::MapIt i(t); i!=INVALID; ++i){
  1446         colBounds(*i, lower, upper);
  1447       }
  1448     }
  1449 #endif
  1450 
  1451     /// Set the lower bound of a row (i.e a constraint)
  1452 
  1453     /// The lower bound of a constraint (row) has to be given by an
  1454     /// extended number of type Value, i.e. a finite number of type
  1455     /// Value or -\ref INF.
  1456     void rowLowerBound(Row r, Value value) {
  1457       _setRowLowerBound(rows(id(r)),value);
  1458     }
  1459 
  1460     /// Get the lower bound of a row (i.e a constraint)
  1461 
  1462     /// This function returns the lower bound for row (constraint) \c c
  1463     /// (this might be -\ref INF as well).
  1464     ///\return The lower bound for row \c r
  1465     Value rowLowerBound(Row r) const {
  1466       return _getRowLowerBound(rows(id(r)));
  1467     }
  1468 
  1469     /// Set the upper bound of a row (i.e a constraint)
  1470 
  1471     /// The upper bound of a constraint (row) has to be given by an
  1472     /// extended number of type Value, i.e. a finite number of type
  1473     /// Value or -\ref INF.
  1474     void rowUpperBound(Row r, Value value) {
  1475       _setRowUpperBound(rows(id(r)),value);
  1476     }
  1477 
  1478     /// Get the upper bound of a row (i.e a constraint)
  1479 
  1480     /// This function returns the upper bound for row (constraint) \c c
  1481     /// (this might be -\ref INF as well).
  1482     ///\return The upper bound for row \c r
  1483     Value rowUpperBound(Row r) const {
  1484       return _getRowUpperBound(rows(id(r)));
  1485     }
  1486 
  1487     ///Set an element of the objective function
  1488     void objCoeff(Col c, Value v) {_setObjCoeff(cols(id(c)),v); };
  1489 
  1490     ///Get an element of the objective function
  1491     Value objCoeff(Col c) const { return _getObjCoeff(cols(id(c))); };
  1492 
  1493     ///Set the objective function
  1494 
  1495     ///\param e is a linear expression of type \ref Expr.
  1496     ///
  1497     void obj(const Expr& e) {
  1498       _setObjCoeffs(ExprIterator(e.comps.begin(), cols),
  1499                     ExprIterator(e.comps.end(), cols));
  1500       obj_const_comp = *e;
  1501     }
  1502 
  1503     ///Get the objective function
  1504 
  1505     ///\return the objective function as a linear expression of type
  1506     ///Expr.
  1507     Expr obj() const {
  1508       Expr e;
  1509       _getObjCoeffs(InsertIterator(e.comps, cols));
  1510       *e = obj_const_comp;
  1511       return e;
  1512     }
  1513 
  1514 
  1515     ///Set the direction of optimization
  1516     void sense(Sense sense) { _setSense(sense); }
  1517 
  1518     ///Query the direction of the optimization
  1519     Sense sense() const {return _getSense(); }
  1520 
  1521     ///Set the sense to maximization
  1522     void max() { _setSense(MAX); }
  1523 
  1524     ///Set the sense to maximization
  1525     void min() { _setSense(MIN); }
  1526 
  1527     ///Clears the problem
  1528     void clear() { _clear(); }
  1529 
  1530     ///@}
  1531 
  1532   };
  1533 
  1534   /// Addition
  1535 
  1536   ///\relates LpBase::Expr
  1537   ///
  1538   inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
  1539     LpBase::Expr tmp(a);
  1540     tmp+=b;
  1541     return tmp;
  1542   }
  1543   ///Substraction
  1544 
  1545   ///\relates LpBase::Expr
  1546   ///
  1547   inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
  1548     LpBase::Expr tmp(a);
  1549     tmp-=b;
  1550     return tmp;
  1551   }
  1552   ///Multiply with constant
  1553 
  1554   ///\relates LpBase::Expr
  1555   ///
  1556   inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) {
  1557     LpBase::Expr tmp(a);
  1558     tmp*=b;
  1559     return tmp;
  1560   }
  1561 
  1562   ///Multiply with constant
  1563 
  1564   ///\relates LpBase::Expr
  1565   ///
  1566   inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) {
  1567     LpBase::Expr tmp(b);
  1568     tmp*=a;
  1569     return tmp;
  1570   }
  1571   ///Divide with constant
  1572 
  1573   ///\relates LpBase::Expr
  1574   ///
  1575   inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) {
  1576     LpBase::Expr tmp(a);
  1577     tmp/=b;
  1578     return tmp;
  1579   }
  1580 
  1581   ///Create constraint
  1582 
  1583   ///\relates LpBase::Constr
  1584   ///
  1585   inline LpBase::Constr operator<=(const LpBase::Expr &e,
  1586                                    const LpBase::Expr &f) {
  1587     return LpBase::Constr(0, f - e, LpBase::INF);
  1588   }
  1589 
  1590   ///Create constraint
  1591 
  1592   ///\relates LpBase::Constr
  1593   ///
  1594   inline LpBase::Constr operator<=(const LpBase::Value &e,
  1595                                    const LpBase::Expr &f) {
  1596     return LpBase::Constr(e, f, LpBase::NaN);
  1597   }
  1598 
  1599   ///Create constraint
  1600 
  1601   ///\relates LpBase::Constr
  1602   ///
  1603   inline LpBase::Constr operator<=(const LpBase::Expr &e,
  1604                                    const LpBase::Value &f) {
  1605     return LpBase::Constr(- LpBase::INF, e, f);
  1606   }
  1607 
  1608   ///Create constraint
  1609 
  1610   ///\relates LpBase::Constr
  1611   ///
  1612   inline LpBase::Constr operator>=(const LpBase::Expr &e,
  1613                                    const LpBase::Expr &f) {
  1614     return LpBase::Constr(0, e - f, LpBase::INF);
  1615   }
  1616 
  1617 
  1618   ///Create constraint
  1619 
  1620   ///\relates LpBase::Constr
  1621   ///
  1622   inline LpBase::Constr operator>=(const LpBase::Value &e,
  1623                                    const LpBase::Expr &f) {
  1624     return LpBase::Constr(LpBase::NaN, f, e);
  1625   }
  1626 
  1627 
  1628   ///Create constraint
  1629 
  1630   ///\relates LpBase::Constr
  1631   ///
  1632   inline LpBase::Constr operator>=(const LpBase::Expr &e,
  1633                                    const LpBase::Value &f) {
  1634     return LpBase::Constr(f, e, LpBase::INF);
  1635   }
  1636 
  1637   ///Create constraint
  1638 
  1639   ///\relates LpBase::Constr
  1640   ///
  1641   inline LpBase::Constr operator==(const LpBase::Expr &e,
  1642                                    const LpBase::Value &f) {
  1643     return LpBase::Constr(f, e, f);
  1644   }
  1645 
  1646   ///Create constraint
  1647 
  1648   ///\relates LpBase::Constr
  1649   ///
  1650   inline LpBase::Constr operator==(const LpBase::Expr &e,
  1651                                    const LpBase::Expr &f) {
  1652     return LpBase::Constr(0, f - e, 0);
  1653   }
  1654 
  1655   ///Create constraint
  1656 
  1657   ///\relates LpBase::Constr
  1658   ///
  1659   inline LpBase::Constr operator<=(const LpBase::Value &n,
  1660                                    const LpBase::Constr &c) {
  1661     LpBase::Constr tmp(c);
  1662     LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
  1663     tmp.lowerBound()=n;
  1664     return tmp;
  1665   }
  1666   ///Create constraint
  1667 
  1668   ///\relates LpBase::Constr
  1669   ///
  1670   inline LpBase::Constr operator<=(const LpBase::Constr &c,
  1671                                    const LpBase::Value &n)
  1672   {
  1673     LpBase::Constr tmp(c);
  1674     LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
  1675     tmp.upperBound()=n;
  1676     return tmp;
  1677   }
  1678 
  1679   ///Create constraint
  1680 
  1681   ///\relates LpBase::Constr
  1682   ///
  1683   inline LpBase::Constr operator>=(const LpBase::Value &n,
  1684                                    const LpBase::Constr &c) {
  1685     LpBase::Constr tmp(c);
  1686     LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
  1687     tmp.upperBound()=n;
  1688     return tmp;
  1689   }
  1690   ///Create constraint
  1691 
  1692   ///\relates LpBase::Constr
  1693   ///
  1694   inline LpBase::Constr operator>=(const LpBase::Constr &c,
  1695                                    const LpBase::Value &n)
  1696   {
  1697     LpBase::Constr tmp(c);
  1698     LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
  1699     tmp.lowerBound()=n;
  1700     return tmp;
  1701   }
  1702 
  1703   ///Addition
  1704 
  1705   ///\relates LpBase::DualExpr
  1706   ///
  1707   inline LpBase::DualExpr operator+(const LpBase::DualExpr &a,
  1708                                     const LpBase::DualExpr &b) {
  1709     LpBase::DualExpr tmp(a);
  1710     tmp+=b;
  1711     return tmp;
  1712   }
  1713   ///Substraction
  1714 
  1715   ///\relates LpBase::DualExpr
  1716   ///
  1717   inline LpBase::DualExpr operator-(const LpBase::DualExpr &a,
  1718                                     const LpBase::DualExpr &b) {
  1719     LpBase::DualExpr tmp(a);
  1720     tmp-=b;
  1721     return tmp;
  1722   }
  1723   ///Multiply with constant
  1724 
  1725   ///\relates LpBase::DualExpr
  1726   ///
  1727   inline LpBase::DualExpr operator*(const LpBase::DualExpr &a,
  1728                                     const LpBase::Value &b) {
  1729     LpBase::DualExpr tmp(a);
  1730     tmp*=b;
  1731     return tmp;
  1732   }
  1733 
  1734   ///Multiply with constant
  1735 
  1736   ///\relates LpBase::DualExpr
  1737   ///
  1738   inline LpBase::DualExpr operator*(const LpBase::Value &a,
  1739                                     const LpBase::DualExpr &b) {
  1740     LpBase::DualExpr tmp(b);
  1741     tmp*=a;
  1742     return tmp;
  1743   }
  1744   ///Divide with constant
  1745 
  1746   ///\relates LpBase::DualExpr
  1747   ///
  1748   inline LpBase::DualExpr operator/(const LpBase::DualExpr &a,
  1749                                     const LpBase::Value &b) {
  1750     LpBase::DualExpr tmp(a);
  1751     tmp/=b;
  1752     return tmp;
  1753   }
  1754 
  1755   /// \ingroup lp_group
  1756   ///
  1757   /// \brief Common base class for LP solvers
  1758   ///
  1759   /// This class is an abstract base class for LP solvers. This class
  1760   /// provides a full interface for set and modify an LP problem,
  1761   /// solve it and retrieve the solution. You can use one of the
  1762   /// descendants as a concrete implementation, or the \c Lp
  1763   /// default LP solver. However, if you would like to handle LP
  1764   /// solvers as reference or pointer in a generic way, you can use
  1765   /// this class directly.
  1766   class LpSolver : virtual public LpBase {
  1767   public:
  1768 
  1769     /// The problem types for primal and dual problems
  1770     enum ProblemType {
  1771       ///Feasible solution hasn't been found (but may exist).
  1772       UNDEFINED = 0,
  1773       ///The problem has no feasible solution
  1774       INFEASIBLE = 1,
  1775       ///Feasible solution found
  1776       FEASIBLE = 2,
  1777       ///Optimal solution exists and found
  1778       OPTIMAL = 3,
  1779       ///The cost function is unbounded
  1780       UNBOUNDED = 4
  1781     };
  1782 
  1783     ///The basis status of variables
  1784     enum VarStatus {
  1785       /// The variable is in the basis
  1786       BASIC, 
  1787       /// The variable is free, but not basic
  1788       FREE,
  1789       /// The variable has active lower bound 
  1790       LOWER,
  1791       /// The variable has active upper bound
  1792       UPPER,
  1793       /// The variable is non-basic and fixed
  1794       FIXED
  1795     };
  1796 
  1797   protected:
  1798 
  1799     virtual SolveExitStatus _solve() = 0;
  1800 
  1801     virtual Value _getPrimal(int i) const = 0;
  1802     virtual Value _getDual(int i) const = 0;
  1803 
  1804     virtual Value _getPrimalRay(int i) const = 0;
  1805     virtual Value _getDualRay(int i) const = 0;
  1806 
  1807     virtual Value _getPrimalValue() const = 0;
  1808 
  1809     virtual VarStatus _getColStatus(int i) const = 0;
  1810     virtual VarStatus _getRowStatus(int i) const = 0;
  1811 
  1812     virtual ProblemType _getPrimalType() const = 0;
  1813     virtual ProblemType _getDualType() const = 0;
  1814 
  1815   public:
  1816 
  1817     ///Allocate a new LP problem instance
  1818     virtual LpSolver* newSolver() const = 0;
  1819     ///Make a copy of the LP problem
  1820     virtual LpSolver* cloneSolver() const = 0;
  1821 
  1822     ///\name Solve the LP
  1823 
  1824     ///@{
  1825 
  1826     ///\e Solve the LP problem at hand
  1827     ///
  1828     ///\return The result of the optimization procedure. Possible
  1829     ///values and their meanings can be found in the documentation of
  1830     ///\ref SolveExitStatus.
  1831     SolveExitStatus solve() { return _solve(); }
  1832 
  1833     ///@}
  1834 
  1835     ///\name Obtain the solution
  1836 
  1837     ///@{
  1838 
  1839     /// The type of the primal problem
  1840     ProblemType primalType() const {
  1841       return _getPrimalType();
  1842     }
  1843 
  1844     /// The type of the dual problem
  1845     ProblemType dualType() const {
  1846       return _getDualType();
  1847     }
  1848 
  1849     /// Return the primal value of the column
  1850 
  1851     /// Return the primal value of the column.
  1852     /// \pre The problem is solved.
  1853     Value primal(Col c) const { return _getPrimal(cols(id(c))); }
  1854 
  1855     /// Return the primal value of the expression
  1856 
  1857     /// Return the primal value of the expression, i.e. the dot
  1858     /// product of the primal solution and the expression.
  1859     /// \pre The problem is solved.
  1860     Value primal(const Expr& e) const {
  1861       double res = *e;
  1862       for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
  1863         res += *c * primal(c);
  1864       }
  1865       return res;
  1866     }
  1867     /// Returns a component of the primal ray
  1868     
  1869     /// The primal ray is solution of the modified primal problem,
  1870     /// where we change each finite bound to 0, and we looking for a
  1871     /// negative objective value in case of minimization, and positive
  1872     /// objective value for maximization. If there is such solution,
  1873     /// that proofs the unsolvability of the dual problem, and if a
  1874     /// feasible primal solution exists, then the unboundness of
  1875     /// primal problem.
  1876     ///
  1877     /// \pre The problem is solved and the dual problem is infeasible.
  1878     /// \note Some solvers does not provide primal ray calculation
  1879     /// functions.
  1880     Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); }
  1881 
  1882     /// Return the dual value of the row
  1883 
  1884     /// Return the dual value of the row.
  1885     /// \pre The problem is solved.
  1886     Value dual(Row r) const { return _getDual(rows(id(r))); }
  1887 
  1888     /// Return the dual value of the dual expression
  1889 
  1890     /// Return the dual value of the dual expression, i.e. the dot
  1891     /// product of the dual solution and the dual expression.
  1892     /// \pre The problem is solved.
  1893     Value dual(const DualExpr& e) const {
  1894       double res = 0.0;
  1895       for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) {
  1896         res += *r * dual(r);
  1897       }
  1898       return res;
  1899     }
  1900 
  1901     /// Returns a component of the dual ray
  1902     
  1903     /// The dual ray is solution of the modified primal problem, where
  1904     /// we change each finite bound to 0 (i.e. the objective function
  1905     /// coefficients in the primal problem), and we looking for a
  1906     /// ositive objective value. If there is such solution, that
  1907     /// proofs the unsolvability of the primal problem, and if a
  1908     /// feasible dual solution exists, then the unboundness of
  1909     /// dual problem.
  1910     ///
  1911     /// \pre The problem is solved and the primal problem is infeasible.
  1912     /// \note Some solvers does not provide dual ray calculation
  1913     /// functions.
  1914     Value dualRay(Row r) const { return _getDualRay(rows(id(r))); }
  1915 
  1916     /// Return the basis status of the column
  1917 
  1918     /// \see VarStatus
  1919     VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); }
  1920 
  1921     /// Return the basis status of the row
  1922 
  1923     /// \see VarStatus
  1924     VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); }
  1925 
  1926     ///The value of the objective function
  1927 
  1928     ///\return
  1929     ///- \ref INF or -\ref INF means either infeasibility or unboundedness
  1930     /// of the primal problem, depending on whether we minimize or maximize.
  1931     ///- \ref NaN if no primal solution is found.
  1932     ///- The (finite) objective value if an optimal solution is found.
  1933     Value primal() const { return _getPrimalValue()+obj_const_comp;}
  1934     ///@}
  1935 
  1936   protected:
  1937 
  1938   };
  1939 
  1940 
  1941   /// \ingroup lp_group
  1942   ///
  1943   /// \brief Common base class for MIP solvers
  1944   ///
  1945   /// This class is an abstract base class for MIP solvers. This class
  1946   /// provides a full interface for set and modify an MIP problem,
  1947   /// solve it and retrieve the solution. You can use one of the
  1948   /// descendants as a concrete implementation, or the \c Lp
  1949   /// default MIP solver. However, if you would like to handle MIP
  1950   /// solvers as reference or pointer in a generic way, you can use
  1951   /// this class directly.
  1952   class MipSolver : virtual public LpBase {
  1953   public:
  1954 
  1955     /// The problem types for MIP problems
  1956     enum ProblemType {
  1957       ///Feasible solution hasn't been found (but may exist).
  1958       UNDEFINED = 0,
  1959       ///The problem has no feasible solution
  1960       INFEASIBLE = 1,
  1961       ///Feasible solution found
  1962       FEASIBLE = 2,
  1963       ///Optimal solution exists and found
  1964       OPTIMAL = 3,
  1965       ///The cost function is unbounded
  1966       ///
  1967       ///The Mip or at least the relaxed problem is unbounded
  1968       UNBOUNDED = 4
  1969     };
  1970 
  1971     ///Allocate a new MIP problem instance
  1972     virtual MipSolver* newSolver() const = 0;
  1973     ///Make a copy of the MIP problem
  1974     virtual MipSolver* cloneSolver() const = 0;
  1975 
  1976     ///\name Solve the MIP
  1977 
  1978     ///@{
  1979 
  1980     /// Solve the MIP problem at hand
  1981     ///
  1982     ///\return The result of the optimization procedure. Possible
  1983     ///values and their meanings can be found in the documentation of
  1984     ///\ref SolveExitStatus.
  1985     SolveExitStatus solve() { return _solve(); }
  1986 
  1987     ///@}
  1988 
  1989     ///\name Setting column type
  1990     ///@{
  1991 
  1992     ///Possible variable (column) types (e.g. real, integer, binary etc.)
  1993     enum ColTypes {
  1994       ///Continuous variable (default)
  1995       REAL = 0,
  1996       ///Integer variable
  1997       INTEGER = 1
  1998     };
  1999 
  2000     ///Sets the type of the given column to the given type
  2001 
  2002     ///Sets the type of the given column to the given type.
  2003     ///
  2004     void colType(Col c, ColTypes col_type) {
  2005       _setColType(cols(id(c)),col_type);
  2006     }
  2007 
  2008     ///Gives back the type of the column.
  2009 
  2010     ///Gives back the type of the column.
  2011     ///
  2012     ColTypes colType(Col c) const {
  2013       return _getColType(cols(id(c)));
  2014     }
  2015     ///@}
  2016 
  2017     ///\name Obtain the solution
  2018 
  2019     ///@{
  2020 
  2021     /// The type of the MIP problem
  2022     ProblemType type() const {
  2023       return _getType();
  2024     }
  2025 
  2026     /// Return the value of the row in the solution
  2027 
  2028     ///  Return the value of the row in the solution.
  2029     /// \pre The problem is solved.
  2030     Value sol(Col c) const { return _getSol(cols(id(c))); }
  2031 
  2032     /// Return the value of the expression in the solution
  2033 
  2034     /// Return the value of the expression in the solution, i.e. the
  2035     /// dot product of the solution and the expression.
  2036     /// \pre The problem is solved.
  2037     Value sol(const Expr& e) const {
  2038       double res = *e;
  2039       for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
  2040         res += *c * sol(c);
  2041       }
  2042       return res;
  2043     }
  2044     ///The value of the objective function
  2045     
  2046     ///\return
  2047     ///- \ref INF or -\ref INF means either infeasibility or unboundedness
  2048     /// of the problem, depending on whether we minimize or maximize.
  2049     ///- \ref NaN if no primal solution is found.
  2050     ///- The (finite) objective value if an optimal solution is found.
  2051     Value solValue() const { return _getSolValue()+obj_const_comp;}
  2052     ///@}
  2053 
  2054   protected:
  2055 
  2056     virtual SolveExitStatus _solve() = 0;
  2057     virtual ColTypes _getColType(int col) const = 0;
  2058     virtual void _setColType(int col, ColTypes col_type) = 0;
  2059     virtual ProblemType _getType() const = 0;
  2060     virtual Value _getSol(int i) const = 0;
  2061     virtual Value _getSolValue() const = 0;
  2062 
  2063   };
  2064 
  2065 
  2066 
  2067 } //namespace lemon
  2068 
  2069 #endif //LEMON_LP_BASE_H