COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lp_base.h @ 2309:468a525d5b45

Last change on this file since 2309:468a525d5b45 was 2309:468a525d5b45, checked in by Alpar Juttner, 17 years ago

Make the constructors of ColIt? public.

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