Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

lp_base.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  * lemon/lp_base.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00006  *
00007  * Permission to use, modify and distribute this software is granted
00008  * provided that this copyright notice appears in all copies. For
00009  * precise terms see the accompanying LICENSE file.
00010  *
00011  * This software is provided "AS IS" with no warranty of any kind,
00012  * express or implied, and with no claim as to its suitability for any
00013  * purpose.
00014  *
00015  */
00016 
00017 #ifndef LEMON_LP_BASE_H
00018 #define LEMON_LP_BASE_H
00019 
00020 #include<vector>
00021 #include<map>
00022 #include<limits>
00023 #include<cmath>
00024 
00025 #include<lemon/utility.h>
00026 #include<lemon/error.h>
00027 #include<lemon/invalid.h>
00028 
00032 namespace lemon {
00033   
00035     
00037   class _FixId 
00038   {
00039     std::vector<int> index;
00040     std::vector<int> cross;
00041     int first_free;
00042   public:
00043     _FixId() : first_free(-1) {};
00045 
00048     int fixId(int n) const {return cross[n];}
00050 
00053     int floatingId(int n) const { return index[n];}
00055 
00059     int insert(int n)
00060     {
00061       if(n>=int(cross.size())) {
00062         cross.resize(n+1);
00063         if(first_free==-1) {
00064           cross[n]=index.size();
00065           index.push_back(n);
00066         }
00067         else {
00068           cross[n]=first_free;
00069           int next=index[first_free];
00070           index[first_free]=n;
00071           first_free=next;
00072         }
00073         return cross[n];
00074       }
00076       else throw LogicError(); //floatingId-s must form a continuous range;
00077     }
00079 
00082     void erase(int n) 
00083     {
00084       int fl=index[n];
00085       index[n]=first_free;
00086       first_free=n;
00087       for(int i=fl+1;i<int(cross.size());++i) {
00088         cross[i-1]=cross[i];
00089         index[cross[i]]--;
00090       }
00091       cross.pop_back();
00092     }
00094 
00097     std::size_t maxFixId() { return cross.size()-1; }
00098   
00099   };
00100     
00102   
00105   class LpSolverBase {
00106 
00107   public:
00108 
00110     enum SolveExitStatus {
00114       SOLVED = 0,
00116       UNSOLVED = 1
00117     };
00118       
00120     enum SolutionStatus {
00122 
00125       UNDEFINED = 0,
00127       INFEASIBLE = 1,
00129       FEASIBLE = 2,
00131       OPTIMAL = 3,
00133 
00136       INFINITE = 4
00137     };
00138 
00140     enum ProblemTypes {
00142       PRIMAL_DUAL_FEASIBLE = 0,
00144       PRIMAL_FEASIBLE_DUAL_INFEASIBLE = 1,
00146       PRIMAL_INFEASIBLE_DUAL_FEASIBLE = 2,
00148       PRIMAL_DUAL_INFEASIBLE = 3,
00150       UNKNOWN = 4
00151     };
00152 
00154     typedef double Value;
00156     static const Value INF;
00158     static const Value NaN;
00159     
00161 
00169     class Col {
00170     protected:
00171       int id;
00172       friend class LpSolverBase;
00173     public:
00174       typedef Value ExprValue;
00175       typedef True LpSolverCol;
00176       Col() {}
00177       Col(const Invalid&) : id(-1) {}
00178       bool operator<(Col c) const  {return id<c.id;}
00179       bool operator==(Col c) const  {return id==c.id;}
00180       bool operator!=(Col c) const  {return id==c.id;}
00181     };
00182 
00184 
00192     class Row {
00193     protected:
00194       int id;
00195       friend class LpSolverBase;
00196     public:
00197       typedef Value ExprValue;
00198       typedef True LpSolverRow;
00199       Row() {}
00200       Row(const Invalid&) : id(-1) {}
00201 
00202       bool operator<(Row c) const  {return id<c.id;}
00203       bool operator==(Row c) const  {return id==c.id;}
00204       bool operator!=(Row c) const  {return id==c.id;} 
00205    };
00206     
00208     
00257     class Expr : public std::map<Col,Value>
00258     {
00259     public:
00260       typedef LpSolverBase::Col Key; 
00261       typedef LpSolverBase::Value Value;
00262       
00263     protected:
00264       typedef std::map<Col,Value> Base;
00265       
00266       Value const_comp;
00267   public:
00268       typedef True IsLinExpression;
00270       Expr() : Base(), const_comp(0) { }
00272       Expr(const Key &v) : const_comp(0) {
00273         Base::insert(std::make_pair(v, 1));
00274       }
00276       Expr(const Value &v) : const_comp(v) {}
00278       void set(const Key &v,const Value &c) {
00279         Base::insert(std::make_pair(v, c));
00280       }
00282       Value &constComp() { return const_comp; }
00284       const Value &constComp() const { return const_comp; }
00285       
00287       void simplify() {
00288         for (Base::iterator i=Base::begin(); i!=Base::end();) {
00289           Base::iterator j=i;
00290           ++j;
00291           if ((*i).second==0) Base::erase(i);
00292           j=i;
00293         }
00294       }
00295 
00297       void clear() {
00298         Base::clear();
00299         const_comp=0;
00300       }
00301 
00303       Expr &operator+=(const Expr &e) {
00304         for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
00305           (*this)[j->first]+=j->second;
00307         const_comp+=e.const_comp;
00308         return *this;
00309       }
00311       Expr &operator-=(const Expr &e) {
00312         for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
00313           (*this)[j->first]-=j->second;
00314         const_comp-=e.const_comp;
00315         return *this;
00316       }
00318       Expr &operator*=(const Value &c) {
00319         for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
00320           j->second*=c;
00321         const_comp*=c;
00322         return *this;
00323       }
00325       Expr &operator/=(const Value &c) {
00326         for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
00327           j->second/=c;
00328         const_comp/=c;
00329         return *this;
00330       }
00331     };
00332     
00334 
00358     class Constr
00359     {
00360     public:
00361       typedef LpSolverBase::Expr Expr;
00362       typedef Expr::Key Key;
00363       typedef Expr::Value Value;
00364       
00365 //       static const Value INF;
00366 //       static const Value NaN;
00367 
00368     protected:
00369       Expr _expr;
00370       Value _lb,_ub;
00371     public:
00373       Constr() : _expr(), _lb(NaN), _ub(NaN) {}
00375       Constr(Value lb,const Expr &e,Value ub) :
00376         _expr(e), _lb(lb), _ub(ub) {}
00378       Constr(const Expr &e,Value ub) : 
00379         _expr(e), _lb(NaN), _ub(ub) {}
00381       Constr(Value lb,const Expr &e) :
00382         _expr(e), _lb(lb), _ub(NaN) {}
00384       Constr(const Expr &e) : 
00385         _expr(e), _lb(NaN), _ub(NaN) {}
00387       void clear() 
00388       {
00389         _expr.clear();
00390         _lb=_ub=NaN;
00391       }
00392 
00394       Expr &expr() { return _expr; }
00396       const Expr &expr() const { return _expr; }
00398 
00403       Value &lowerBound() { return _lb; }
00405       const Value &lowerBound() const { return _lb; }
00407 
00412       Value &upperBound() { return _ub; }
00414       const Value &upperBound() const { return _ub; }
00416       bool lowerBounded() const { 
00417         using namespace std;
00418         return finite(_lb);
00419       }
00421       bool upperBounded() const {
00422         using namespace std;
00423         return finite(_ub);
00424       }
00425     };
00426     
00428     
00471     class DualExpr : public std::map<Row,Value>
00472     {
00473     public:
00474       typedef LpSolverBase::Row Key; 
00475       typedef LpSolverBase::Value Value;
00476       
00477     protected:
00478       typedef std::map<Row,Value> Base;
00479       
00480     public:
00481       typedef True IsLinExpression;
00483       DualExpr() : Base() { }
00485       DualExpr(const Key &v) {
00486         Base::insert(std::make_pair(v, 1));
00487       }
00489       void set(const Key &v,const Value &c) {
00490         Base::insert(std::make_pair(v, c));
00491       }
00492       
00494       void simplify() {
00495         for (Base::iterator i=Base::begin(); i!=Base::end();) {
00496           Base::iterator j=i;
00497           ++j;
00498           if ((*i).second==0) Base::erase(i);
00499           j=i;
00500         }
00501       }
00502 
00504       void clear() {
00505         Base::clear();
00506       }
00507 
00509       DualExpr &operator+=(const DualExpr &e) {
00510         for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
00511           (*this)[j->first]+=j->second;
00513         return *this;
00514       }
00516       DualExpr &operator-=(const DualExpr &e) {
00517         for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
00518           (*this)[j->first]-=j->second;
00519         return *this;
00520       }
00522       DualExpr &operator*=(const Value &c) {
00523         for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
00524           j->second*=c;
00525         return *this;
00526       }
00528       DualExpr &operator/=(const Value &c) {
00529         for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
00530           j->second/=c;
00531         return *this;
00532       }
00533     };
00534     
00535 
00536   protected:
00537     _FixId rows;
00538     _FixId cols;
00539 
00540     //Abstract virtual functions
00541     virtual LpSolverBase &_newLp() = 0;
00542     virtual LpSolverBase &_copyLp(){
00544 
00545       //Starting:
00546       LpSolverBase & newlp(_newLp());
00547       return newlp;
00548       //return *(LpSolverBase*)0;
00549     };
00550 
00551     virtual int _addCol() = 0;
00552     virtual int _addRow() = 0;
00553     virtual void _eraseCol(int col) = 0;
00554     virtual void _eraseRow(int row) = 0;
00555     virtual void _setRowCoeffs(int i, 
00556                                int length,
00557                                int  const * indices, 
00558                                Value  const * values ) = 0;
00559     virtual void _setColCoeffs(int i, 
00560                                int length,
00561                                int  const * indices, 
00562                                Value  const * values ) = 0;
00563     virtual void _setCoeff(int row, int col, Value value) = 0;
00564     virtual void _setColLowerBound(int i, Value value) = 0;
00565     virtual void _setColUpperBound(int i, Value value) = 0;
00566 //     virtual void _setRowLowerBound(int i, Value value) = 0;
00567 //     virtual void _setRowUpperBound(int i, Value value) = 0;
00568     virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
00569     virtual void _setObjCoeff(int i, Value obj_coef) = 0;
00570     virtual void _clearObj()=0;
00571 //     virtual void _setObj(int length,
00572 //                          int  const * indices, 
00573 //                          Value  const * values ) = 0;
00574     virtual SolveExitStatus _solve() = 0;
00575     virtual Value _getPrimal(int i) = 0;
00576     virtual Value _getPrimalValue() = 0;
00577     virtual SolutionStatus _getPrimalStatus() = 0;
00578     virtual SolutionStatus _getDualStatus() = 0;
00581     virtual ProblemTypes _getProblemType() = 0;
00582 
00583     virtual void _setMax() = 0;
00584     virtual void _setMin() = 0;
00585     
00586     //Own protected stuff
00587     
00588     //Constant component of the objective function
00589     Value obj_const_comp;
00590     
00591 
00592 
00593     
00594   public:
00595 
00597     LpSolverBase() : obj_const_comp(0) {}
00598 
00600     virtual ~LpSolverBase() {}
00601 
00603     LpSolverBase &newLp() {return _newLp();}
00605     LpSolverBase &copyLp() {return _copyLp();}
00606     
00608 
00610 
00612     Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;}
00613 
00640 #ifdef DOXYGEN
00641     template<class T>
00642     int addColSet(T &t) { return 0;} 
00643 #else
00644     template<class T>
00645     typename enable_if<typename T::value_type::LpSolverCol,int>::type
00646     addColSet(T &t,dummy<0> = 0) {
00647       int s=0;
00648       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
00649       return s;
00650     }
00651     template<class T>
00652     typename enable_if<typename T::value_type::second_type::LpSolverCol,
00653                        int>::type
00654     addColSet(T &t,dummy<1> = 1) { 
00655       int s=0;
00656       for(typename T::iterator i=t.begin();i!=t.end();++i) {
00657         i->second=addCol();
00658         s++;
00659       }
00660       return s;
00661     }
00662     template<class T>
00663     typename enable_if<typename T::ValueSet::value_type::LpSolverCol,
00664                        int>::type
00665     addColSet(T &t,dummy<2> = 2) { 
00667       int s=0;
00668       for(typename T::ValueSet::iterator i=t.valueSet().begin();
00669           i!=t.valueSet().end();
00670           ++i)
00671         {
00672           *i=addCol();
00673           s++;
00674         }
00675       return s;
00676     }
00677 #endif
00678 
00680 
00685     void setCol(Col c,const DualExpr &e) {
00686       std::vector<int> indices;
00687       std::vector<Value> values;
00688       indices.push_back(0);
00689       values.push_back(0);
00690       for(DualExpr::const_iterator i=e.begin(); i!=e.end(); ++i)
00691         if((*i).second!=0) { 
00692           indices.push_back(cols.floatingId((*i).first.id));
00693           values.push_back((*i).second);
00694         }
00695       _setColCoeffs(cols.floatingId(c.id),indices.size()-1,
00696                     &indices[0],&values[0]);
00697     }
00698 
00700 
00707     Col addCol(const DualExpr &e, Value obj=0) {
00708       Col c=addCol();
00709       setCol(c,e);
00710       objCoeff(c,obj);
00711       return c;
00712     }
00713 
00715 
00718     Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;}
00719 
00746 #ifdef DOXYGEN
00747     template<class T>
00748     int addRowSet(T &t) { return 0;} 
00749 #else
00750     template<class T>
00751     typename enable_if<typename T::value_type::LpSolverRow,int>::type
00752     addRowSet(T &t,dummy<0> = 0) {
00753       int s=0;
00754       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
00755       return s;
00756     }
00757     template<class T>
00758     typename enable_if<typename T::value_type::second_type::LpSolverRow,
00759                        int>::type
00760     addRowSet(T &t,dummy<1> = 1) { 
00761       int s=0;
00762       for(typename T::iterator i=t.begin();i!=t.end();++i) {
00763         i->second=addRow();
00764         s++;
00765       }
00766       return s;
00767     }
00768     template<class T>
00769     typename enable_if<typename T::ValueSet::value_type::LpSolverRow,
00770                        int>::type
00771     addRowSet(T &t,dummy<2> = 2) { 
00773       int s=0;
00774       for(typename T::ValueSet::iterator i=t.valueSet().begin();
00775           i!=t.valueSet().end();
00776           ++i)
00777         {
00778           *i=addRow();
00779           s++;
00780         }
00781       return s;
00782     }
00783 #endif
00784 
00786 
00795     void setRow(Row r, Value l,const Expr &e, Value u) {
00796       std::vector<int> indices;
00797       std::vector<Value> values;
00798       indices.push_back(0);
00799       values.push_back(0);
00800       for(Expr::const_iterator i=e.begin(); i!=e.end(); ++i)
00801         if((*i).second!=0) { 
00802           indices.push_back(cols.floatingId((*i).first.id));
00803           values.push_back((*i).second);
00804         }
00805       _setRowCoeffs(rows.floatingId(r.id),indices.size()-1,
00806                     &indices[0],&values[0]);
00807 //       _setRowLowerBound(rows.floatingId(r.id),l-e.constComp());
00808 //       _setRowUpperBound(rows.floatingId(r.id),u-e.constComp());
00809        _setRowBounds(rows.floatingId(r.id),l-e.constComp(),u-e.constComp());
00810     }
00811 
00813 
00816     void setRow(Row r, const Constr &c) {
00817       setRow(r,
00818              c.lowerBounded()?c.lowerBound():-INF,
00819              c.expr(),
00820              c.upperBounded()?c.upperBound():INF);
00821     }
00822 
00824 
00831     Row addRow(Value l,const Expr &e, Value u) {
00832       Row r=addRow();
00833       setRow(r,l,e,u);
00834       return r;
00835     }
00836 
00838 
00841     Row addRow(const Constr &c) {
00842       Row r=addRow();
00843       setRow(r,c);
00844       return r;
00845     }
00847 
00850     void eraseCol(Col c) {
00851       _eraseCol(cols.floatingId(c.id));
00852       cols.erase(c.id);
00853     }
00855 
00858     void eraseRow(Row r) {
00859       _eraseRow(rows.floatingId(r.id));
00860       rows.erase(r.id);
00861     }
00862 
00864 
00868     void setCoeff(Row r, Col c, Value val){
00869       _setCoeff(rows.floatingId(r.id),cols.floatingId(c.id), val);
00870     }
00871 
00873 
00877     void colLowerBound(Col c, Value value) {
00878       _setColLowerBound(cols.floatingId(c.id),value);
00879     }
00881 
00885     void colUpperBound(Col c, Value value) {
00886       _setColUpperBound(cols.floatingId(c.id),value);
00887     };
00889 
00894     void colBounds(Col c, Value lower, Value upper) {
00895       _setColLowerBound(cols.floatingId(c.id),lower);
00896       _setColUpperBound(cols.floatingId(c.id),upper);
00897     }
00898     
00899 //     /// Set the lower bound of a row (i.e a constraint)
00900 
00901 //     /// The lower bound of a linear expression (row) has to be given by an 
00902 //     /// extended number of type Value, i.e. a finite number of type 
00903 //     /// Value or -\ref INF.
00904 //     void rowLowerBound(Row r, Value value) {
00905 //       _setRowLowerBound(rows.floatingId(r.id),value);
00906 //     };
00907 //     /// Set the upper bound of a row (i.e a constraint)
00908 
00909 //     /// The upper bound of a linear expression (row) has to be given by an 
00910 //     /// extended number of type Value, i.e. a finite number of type 
00911 //     /// Value or \ref INF.
00912 //     void rowUpperBound(Row r, Value value) {
00913 //       _setRowUpperBound(rows.floatingId(r.id),value);
00914 //     };
00915 
00917 
00922     void rowBounds(Row c, Value lower, Value upper) {
00923       _setRowBounds(rows.floatingId(c.id),lower, upper);
00924       // _setRowUpperBound(rows.floatingId(c.id),upper);
00925     }
00926     
00928     void objCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); };
00930     
00933     void setObj(Expr e) {
00934       _clearObj();
00935       for (Expr::iterator i=e.begin(); i!=e.end(); ++i)
00936         objCoeff((*i).first,(*i).second);
00937       obj_const_comp=e.constComp();
00938     }
00939 
00941     void max() { _setMax(); }
00943     void min() { _setMin(); }
00944 
00945     
00947 
00948 
00950 
00952 
00958     SolveExitStatus solve() { return _solve(); }
00959     
00961     
00963 
00965 
00967     SolutionStatus primalStatus() {
00968       return _getPrimalStatus();
00969     }
00970 
00972     SolutionStatus dualStatus() {
00973       return _getDualStatus();
00974     }
00975 
00977     ProblemTypes problemType() {
00978       return _getProblemType();
00979     }
00980 
00982     Value primal(Col c) { return _getPrimal(cols.floatingId(c.id)); }
00983 
00985 
00991     Value primalValue() { return _getPrimalValue()+obj_const_comp;}
00993     
00994   };  
00995 
00997   
01000   inline LpSolverBase::Expr operator+(const LpSolverBase::Expr &a,
01001                                       const LpSolverBase::Expr &b) 
01002   {
01003     LpSolverBase::Expr tmp(a);
01004     tmp+=b; 
01005     return tmp;
01006   }
01008   
01011   inline LpSolverBase::Expr operator-(const LpSolverBase::Expr &a,
01012                                       const LpSolverBase::Expr &b) 
01013   {
01014     LpSolverBase::Expr tmp(a);
01015     tmp-=b; 
01016     return tmp;
01017   }
01019   
01022   inline LpSolverBase::Expr operator*(const LpSolverBase::Expr &a,
01023                                       const LpSolverBase::Value &b) 
01024   {
01025     LpSolverBase::Expr tmp(a);
01026     tmp*=b; 
01027     return tmp;
01028   }
01029   
01031   
01034   inline LpSolverBase::Expr operator*(const LpSolverBase::Value &a,
01035                                       const LpSolverBase::Expr &b) 
01036   {
01037     LpSolverBase::Expr tmp(b);
01038     tmp*=a; 
01039     return tmp;
01040   }
01042   
01045   inline LpSolverBase::Expr operator/(const LpSolverBase::Expr &a,
01046                                       const LpSolverBase::Value &b) 
01047   {
01048     LpSolverBase::Expr tmp(a);
01049     tmp/=b; 
01050     return tmp;
01051   }
01052   
01054   
01057   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
01058                                          const LpSolverBase::Expr &f) 
01059   {
01060     return LpSolverBase::Constr(-LpSolverBase::INF,e-f,0);
01061   }
01062 
01064   
01067   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &e,
01068                                          const LpSolverBase::Expr &f) 
01069   {
01070     return LpSolverBase::Constr(e,f);
01071   }
01072 
01074   
01077   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
01078                                          const LpSolverBase::Value &f) 
01079   {
01080     return LpSolverBase::Constr(e,f);
01081   }
01082 
01084   
01087   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
01088                                          const LpSolverBase::Expr &f) 
01089   {
01090     return LpSolverBase::Constr(-LpSolverBase::INF,f-e,0);
01091   }
01092 
01093 
01095   
01098   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &e,
01099                                          const LpSolverBase::Expr &f) 
01100   {
01101     return LpSolverBase::Constr(f,e);
01102   }
01103 
01104 
01106   
01109   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
01110                                          const LpSolverBase::Value &f) 
01111   {
01112     return LpSolverBase::Constr(f,e);
01113   }
01114 
01116   
01119   inline LpSolverBase::Constr operator==(const LpSolverBase::Expr &e,
01120                                          const LpSolverBase::Expr &f) 
01121   {
01122     return LpSolverBase::Constr(0,e-f,0);
01123   }
01124 
01126   
01129   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &n,
01130                                          const LpSolverBase::Constr&c) 
01131   {
01132     LpSolverBase::Constr tmp(c);
01134     if(!isnan(tmp.lowerBound())) throw LogicError();
01135     else tmp.lowerBound()=n;
01136     return tmp;
01137   }
01139   
01142   inline LpSolverBase::Constr operator<=(const LpSolverBase::Constr& c,
01143                                          const LpSolverBase::Value &n)
01144   {
01145     LpSolverBase::Constr tmp(c);
01147     if(!isnan(tmp.upperBound())) throw LogicError();
01148     else tmp.upperBound()=n;
01149     return tmp;
01150   }
01151 
01153   
01156   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &n,
01157                                          const LpSolverBase::Constr&c) 
01158   {
01159     LpSolverBase::Constr tmp(c);
01161     if(!isnan(tmp.upperBound())) throw LogicError();
01162     else tmp.upperBound()=n;
01163     return tmp;
01164   }
01166   
01169   inline LpSolverBase::Constr operator>=(const LpSolverBase::Constr& c,
01170                                          const LpSolverBase::Value &n)
01171   {
01172     LpSolverBase::Constr tmp(c);
01174     if(!isnan(tmp.lowerBound())) throw LogicError();
01175     else tmp.lowerBound()=n;
01176     return tmp;
01177   }
01178 
01180   
01183   inline LpSolverBase::DualExpr operator+(const LpSolverBase::DualExpr &a,
01184                                       const LpSolverBase::DualExpr &b) 
01185   {
01186     LpSolverBase::DualExpr tmp(a);
01187     tmp+=b; 
01188     return tmp;
01189   }
01191   
01194   inline LpSolverBase::DualExpr operator-(const LpSolverBase::DualExpr &a,
01195                                       const LpSolverBase::DualExpr &b) 
01196   {
01197     LpSolverBase::DualExpr tmp(a);
01198     tmp-=b; 
01199     return tmp;
01200   }
01202   
01205   inline LpSolverBase::DualExpr operator*(const LpSolverBase::DualExpr &a,
01206                                       const LpSolverBase::Value &b) 
01207   {
01208     LpSolverBase::DualExpr tmp(a);
01209     tmp*=b; 
01210     return tmp;
01211   }
01212   
01214   
01217   inline LpSolverBase::DualExpr operator*(const LpSolverBase::Value &a,
01218                                       const LpSolverBase::DualExpr &b) 
01219   {
01220     LpSolverBase::DualExpr tmp(b);
01221     tmp*=a; 
01222     return tmp;
01223   }
01225   
01228   inline LpSolverBase::DualExpr operator/(const LpSolverBase::DualExpr &a,
01229                                       const LpSolverBase::Value &b) 
01230   {
01231     LpSolverBase::DualExpr tmp(a);
01232     tmp/=b; 
01233     return tmp;
01234   }
01235   
01236 
01237 } //namespace lemon
01238 
01239 #endif //LEMON_LP_BASE_H

Generated on Sat Aug 27 14:14:53 2005 for LEMON by  doxygen 1.4.4