COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lp_base.h @ 2327:596e48d6e77b

Last change on this file since 2327:596e48d6e77b was 2324:18fc834761d9, checked in by athos, 17 years ago

Some query functions got implemented, but only for GLPK.

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