COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lp_base.h @ 1852:ffa7c6e96330

Last change on this file since 1852:ffa7c6e96330 was 1840:173b53b28d7c, checked in by marci, 14 years ago

max flow with lp column generation

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