COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lp_base.h @ 2190:dd887831e9c1

Last change on this file since 2190:dd887831e9c1 was 2185:e2bf51eab7f7, checked in by athos, 18 years ago

Fixed the mip error (mipstatus was incorrect).

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