lp_base.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  *
00003  * This file is a part of LEMON, a generic C++ optimization library
00004  *
00005  * Copyright (C) 2003-2006
00006  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00007  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00008  *
00009  * Permission to use, modify and distribute this software is granted
00010  * provided that this copyright notice appears in all copies. For
00011  * precise terms see the accompanying LICENSE file.
00012  *
00013  * This software is provided "AS IS" with no warranty of any kind,
00014  * express or implied, and with no claim as to its suitability for any
00015  * purpose.
00016  *
00017  */
00018 
00019 #ifndef LEMON_LP_BASE_H
00020 #define LEMON_LP_BASE_H
00021 
00022 #include<vector>
00023 #include<map>
00024 #include<limits>
00025 #include<cmath>
00026 
00027 #include<lemon/utility.h>
00028 #include<lemon/error.h>
00029 #include<lemon/invalid.h>
00030 
00034 namespace lemon {
00035   
00037     
00039   class _FixId 
00040   {
00041   protected:
00042     std::vector<int> index;
00043     std::vector<int> cross;
00044     int first_free;
00045   public:
00046     _FixId() : first_free(-1) {};
00048 
00051     int fixId(int n) const {return cross[n];}
00053 
00056     int floatingId(int n) const { return index[n];}
00058 
00062     int insert(int n)
00063     {
00064       if(n>=int(cross.size())) {
00065         cross.resize(n+1);
00066         if(first_free==-1) {
00067           cross[n]=index.size();
00068           index.push_back(n);
00069         }
00070         else {
00071           cross[n]=first_free;
00072           int next=index[first_free];
00073           index[first_free]=n;
00074           first_free=next;
00075         }
00076         return cross[n];
00077       }
00079       else throw LogicError(); //floatingId-s must form a continuous range;
00080     }
00082 
00085     void erase(int n) 
00086     {
00087       int fl=index[n];
00088       index[n]=first_free;
00089       first_free=n;
00090       for(int i=fl+1;i<int(cross.size());++i) {
00091         cross[i-1]=cross[i];
00092         index[cross[i]]--;
00093       }
00094       cross.pop_back();
00095     }
00097 
00100     std::size_t maxFixId() { return cross.size()-1; }
00101   
00102   };
00103     
00105   
00108   class LpSolverBase {
00109 
00110   public:
00111 
00113     enum SolveExitStatus {
00117       SOLVED = 0,
00119       UNSOLVED = 1
00120     };
00121       
00123     enum SolutionStatus {
00125 
00128       UNDEFINED = 0,
00130       INFEASIBLE = 1,
00132       FEASIBLE = 2,
00134       OPTIMAL = 3,
00136 
00139       INFINITE = 4
00140     };
00141 
00143     enum ProblemTypes {
00145       PRIMAL_DUAL_FEASIBLE = 0,
00147       PRIMAL_FEASIBLE_DUAL_INFEASIBLE = 1,
00149       PRIMAL_INFEASIBLE_DUAL_FEASIBLE = 2,
00151       PRIMAL_DUAL_INFEASIBLE = 3,
00153       UNKNOWN = 4
00154     };
00155 
00157     typedef double Value;
00159     static const Value INF;
00161     static const Value NaN;
00162     
00164 
00172     class Col {
00173     protected:
00174       int id;
00175       friend class LpSolverBase;
00176     public:
00177       typedef Value ExprValue;
00178       typedef True LpSolverCol;
00179       Col() {}
00180       Col(const Invalid&) : id(-1) {}
00181       bool operator< (Col c) const  {return id< c.id;}
00182       bool operator> (Col c) const  {return id> c.id;}
00183       bool operator==(Col c) const  {return id==c.id;}
00184       bool operator!=(Col c) const  {return id!=c.id;}
00185     };
00186 
00188 
00196     class Row {
00197     protected:
00198       int id;
00199       friend class LpSolverBase;
00200     public:
00201       typedef Value ExprValue;
00202       typedef True LpSolverRow;
00203       Row() {}
00204       Row(const Invalid&) : id(-1) {}
00205 
00206       bool operator< (Row c) const  {return id< c.id;}
00207       bool operator> (Row c) const  {return id> c.id;}
00208       bool operator==(Row c) const  {return id==c.id;}
00209       bool operator!=(Row c) const  {return id!=c.id;} 
00210    };
00211     
00213     
00262     class Expr : public std::map<Col,Value>
00263     {
00264     public:
00265       typedef LpSolverBase::Col Key; 
00266       typedef LpSolverBase::Value Value;
00267       
00268     protected:
00269       typedef std::map<Col,Value> Base;
00270       
00271       Value const_comp;
00272   public:
00273       typedef True IsLinExpression;
00275       Expr() : Base(), const_comp(0) { }
00277       Expr(const Key &v) : const_comp(0) {
00278         Base::insert(std::make_pair(v, 1));
00279       }
00281       Expr(const Value &v) : const_comp(v) {}
00283       void set(const Key &v,const Value &c) {
00284         Base::insert(std::make_pair(v, c));
00285       }
00287       Value &constComp() { return const_comp; }
00289       const Value &constComp() const { return const_comp; }
00290       
00292       void simplify() {
00293         for (Base::iterator i=Base::begin(); i!=Base::end();) {
00294           Base::iterator j=i;
00295           ++j;
00296           if ((*i).second==0) Base::erase(i);
00297           j=i;
00298         }
00299       }
00300 
00302       void simplify(double &tolerance) {
00303         for (Base::iterator i=Base::begin(); i!=Base::end();) {
00304           Base::iterator j=i;
00305           ++j;
00306           if (std::fabs((*i).second)<tolerance) Base::erase(i);
00307           j=i;
00308         }
00309       }
00310 
00312       void clear() {
00313         Base::clear();
00314         const_comp=0;
00315       }
00316 
00318       Expr &operator+=(const Expr &e) {
00319         for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
00320           (*this)[j->first]+=j->second;
00321         const_comp+=e.const_comp;
00322         return *this;
00323       }
00325       Expr &operator-=(const Expr &e) {
00326         for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
00327           (*this)[j->first]-=j->second;
00328         const_comp-=e.const_comp;
00329         return *this;
00330       }
00332       Expr &operator*=(const Value &c) {
00333         for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
00334           j->second*=c;
00335         const_comp*=c;
00336         return *this;
00337       }
00339       Expr &operator/=(const Value &c) {
00340         for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
00341           j->second/=c;
00342         const_comp/=c;
00343         return *this;
00344       }
00345     };
00346     
00348 
00373     class Constr
00374     {
00375     public:
00376       typedef LpSolverBase::Expr Expr;
00377       typedef Expr::Key Key;
00378       typedef Expr::Value Value;
00379       
00380 //       static const Value INF;
00381 //       static const Value NaN;
00382 
00383     protected:
00384       Expr _expr;
00385       Value _lb,_ub;
00386     public:
00388       Constr() : _expr(), _lb(NaN), _ub(NaN) {}
00390       Constr(Value lb,const Expr &e,Value ub) :
00391         _expr(e), _lb(lb), _ub(ub) {}
00393       Constr(const Expr &e,Value ub) : 
00394         _expr(e), _lb(NaN), _ub(ub) {}
00396       Constr(Value lb,const Expr &e) :
00397         _expr(e), _lb(lb), _ub(NaN) {}
00399       Constr(const Expr &e) : 
00400         _expr(e), _lb(NaN), _ub(NaN) {}
00402       void clear() 
00403       {
00404         _expr.clear();
00405         _lb=_ub=NaN;
00406       }
00407 
00409       Expr &expr() { return _expr; }
00411       const Expr &expr() const { return _expr; }
00413 
00418       Value &lowerBound() { return _lb; }
00420       const Value &lowerBound() const { return _lb; }
00422 
00427       Value &upperBound() { return _ub; }
00429       const Value &upperBound() const { return _ub; }
00431       bool lowerBounded() const { 
00432         using namespace std;
00433         return finite(_lb);
00434       }
00436       bool upperBounded() const {
00437         using namespace std;
00438         return finite(_ub);
00439       }
00440     };
00441     
00443     
00486     class DualExpr : public std::map<Row,Value>
00487     {
00488     public:
00489       typedef LpSolverBase::Row Key; 
00490       typedef LpSolverBase::Value Value;
00491       
00492     protected:
00493       typedef std::map<Row,Value> Base;
00494       
00495     public:
00496       typedef True IsLinExpression;
00498       DualExpr() : Base() { }
00500       DualExpr(const Key &v) {
00501         Base::insert(std::make_pair(v, 1));
00502       }
00504       void set(const Key &v,const Value &c) {
00505         Base::insert(std::make_pair(v, c));
00506       }
00507       
00509       void simplify() {
00510         for (Base::iterator i=Base::begin(); i!=Base::end();) {
00511           Base::iterator j=i;
00512           ++j;
00513           if ((*i).second==0) Base::erase(i);
00514           j=i;
00515         }
00516       }
00517 
00519       void simplify(double &tolerance) {
00520         for (Base::iterator i=Base::begin(); i!=Base::end();) {
00521           Base::iterator j=i;
00522           ++j;
00523           if (std::fabs((*i).second)<tolerance) Base::erase(i);
00524           j=i;
00525         }
00526       }
00527 
00528 
00530       void clear() {
00531         Base::clear();
00532       }
00533 
00535       DualExpr &operator+=(const DualExpr &e) {
00536         for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
00537           (*this)[j->first]+=j->second;
00538         return *this;
00539       }
00541       DualExpr &operator-=(const DualExpr &e) {
00542         for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
00543           (*this)[j->first]-=j->second;
00544         return *this;
00545       }
00547       DualExpr &operator*=(const Value &c) {
00548         for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
00549           j->second*=c;
00550         return *this;
00551       }
00553       DualExpr &operator/=(const Value &c) {
00554         for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
00555           j->second/=c;
00556         return *this;
00557       }
00558     };
00559     
00560 
00561   protected:
00562     _FixId rows;
00563     _FixId cols;
00564 
00565     //Abstract virtual functions
00566     virtual LpSolverBase &_newLp() = 0;
00567     virtual LpSolverBase &_copyLp(){
00569 
00570       //Starting:
00571       LpSolverBase & newlp(_newLp());
00572       return newlp;
00573       //return *(LpSolverBase*)0;
00574     };
00575 
00576     virtual int _addCol() = 0;
00577     virtual int _addRow() = 0;
00578     virtual void _eraseCol(int col) = 0;
00579     virtual void _eraseRow(int row) = 0;
00580     virtual void _getColName(int col,       std::string & name) = 0;
00581     virtual void _setColName(int col, const std::string & name) = 0;
00582     virtual void _setRowCoeffs(int i, 
00583                                int length,
00584                                int  const * indices, 
00585                                Value  const * values ) = 0;
00586     virtual void _setColCoeffs(int i, 
00587                                int length,
00588                                int  const * indices, 
00589                                Value  const * values ) = 0;
00590     virtual void _setCoeff(int row, int col, Value value) = 0;
00591     virtual void _setColLowerBound(int i, Value value) = 0;
00592     virtual void _setColUpperBound(int i, Value value) = 0;
00593 //     virtual void _setRowLowerBound(int i, Value value) = 0;
00594 //     virtual void _setRowUpperBound(int i, Value value) = 0;
00595     virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
00596     virtual void _setObjCoeff(int i, Value obj_coef) = 0;
00597     virtual void _clearObj()=0;
00598 //     virtual void _setObj(int length,
00599 //                          int  const * indices, 
00600 //                          Value  const * values ) = 0;
00601     virtual SolveExitStatus _solve() = 0;
00602     virtual Value _getPrimal(int i) = 0;
00603     virtual Value _getDual(int i) = 0;
00604     virtual Value _getPrimalValue() = 0;
00605     virtual bool _isBasicCol(int i) = 0;
00606     virtual SolutionStatus _getPrimalStatus() = 0;
00607     virtual SolutionStatus _getDualStatus() = 0;
00610     virtual ProblemTypes _getProblemType() = 0;
00611 
00612     virtual void _setMax() = 0;
00613     virtual void _setMin() = 0;
00614     
00615     //Own protected stuff
00616     
00617     //Constant component of the objective function
00618     Value obj_const_comp;
00619     
00620 
00621 
00622     
00623   public:
00624 
00626     LpSolverBase() : obj_const_comp(0) {}
00627 
00629     virtual ~LpSolverBase() {}
00630 
00632     LpSolverBase &newLp() {return _newLp();}
00634     LpSolverBase &copyLp() {return _copyLp();}
00635     
00637 
00639 
00641     Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;}
00642 
00669 #ifdef DOXYGEN
00670     template<class T>
00671     int addColSet(T &t) { return 0;} 
00672 #else
00673     template<class T>
00674     typename enable_if<typename T::value_type::LpSolverCol,int>::type
00675     addColSet(T &t,dummy<0> = 0) {
00676       int s=0;
00677       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
00678       return s;
00679     }
00680     template<class T>
00681     typename enable_if<typename T::value_type::second_type::LpSolverCol,
00682                        int>::type
00683     addColSet(T &t,dummy<1> = 1) { 
00684       int s=0;
00685       for(typename T::iterator i=t.begin();i!=t.end();++i) {
00686         i->second=addCol();
00687         s++;
00688       }
00689       return s;
00690     }
00691     template<class T>
00692     typename enable_if<typename T::MapIt::Value::LpSolverCol,
00693                        int>::type
00694     addColSet(T &t,dummy<2> = 2) { 
00695       int s=0;
00696       for(typename T::MapIt i(t); i!=INVALID; ++i)
00697         {
00698           i.set(addCol());
00699           s++;
00700         }
00701       return s;
00702     }
00703 #endif
00704 
00706 
00710     void col(Col c,const DualExpr &e) {
00711       std::vector<int> indices;
00712       std::vector<Value> values;
00713       indices.push_back(0);
00714       values.push_back(0);
00715       for(DualExpr::const_iterator i=e.begin(); i!=e.end(); ++i)
00716         if((*i).second!=0) {
00717           indices.push_back(rows.floatingId((*i).first.id));
00718           values.push_back((*i).second);
00719         }
00720       _setColCoeffs(cols.floatingId(c.id),indices.size()-1,
00721                     &indices[0],&values[0]);
00722     }
00723 
00725 
00730     Col addCol(const DualExpr &e, Value obj=0) {
00731       Col c=addCol();
00732       col(c,e);
00733       objCoeff(c,obj);
00734       return c;
00735     }
00736 
00738 
00741     Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;}
00742 
00769 #ifdef DOXYGEN
00770     template<class T>
00771     int addRowSet(T &t) { return 0;} 
00772 #else
00773     template<class T>
00774     typename enable_if<typename T::value_type::LpSolverRow,int>::type
00775     addRowSet(T &t,dummy<0> = 0) {
00776       int s=0;
00777       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
00778       return s;
00779     }
00780     template<class T>
00781     typename enable_if<typename T::value_type::second_type::LpSolverRow,
00782                        int>::type
00783     addRowSet(T &t,dummy<1> = 1) { 
00784       int s=0;
00785       for(typename T::iterator i=t.begin();i!=t.end();++i) {
00786         i->second=addRow();
00787         s++;
00788       }
00789       return s;
00790     }
00791     template<class T>
00792     typename enable_if<typename T::MapIt::Value::LpSolverRow,
00793                        int>::type
00794     addRowSet(T &t,dummy<2> = 2) { 
00795       int s=0;
00796       for(typename T::MapIt i(t); i!=INVALID; ++i)
00797         {
00798           i.set(addRow());
00799           s++;
00800         }
00801       return s;
00802     }
00803 #endif
00804 
00806 
00815     void row(Row r, Value l,const Expr &e, Value u) {
00816       std::vector<int> indices;
00817       std::vector<Value> values;
00818       indices.push_back(0);
00819       values.push_back(0);
00820       for(Expr::const_iterator i=e.begin(); i!=e.end(); ++i)
00821         if((*i).second!=0) { 
00822           indices.push_back(cols.floatingId((*i).first.id));
00823           values.push_back((*i).second);
00824         }
00825       _setRowCoeffs(rows.floatingId(r.id),indices.size()-1,
00826                     &indices[0],&values[0]);
00827 //       _setRowLowerBound(rows.floatingId(r.id),l-e.constComp());
00828 //       _setRowUpperBound(rows.floatingId(r.id),u-e.constComp());
00829        _setRowBounds(rows.floatingId(r.id),l-e.constComp(),u-e.constComp());
00830     }
00831 
00833 
00836     void row(Row r, const Constr &c) {
00837       row(r,
00838              c.lowerBounded()?c.lowerBound():-INF,
00839              c.expr(),
00840              c.upperBounded()?c.upperBound():INF);
00841     }
00842 
00844 
00851     Row addRow(Value l,const Expr &e, Value u) {
00852       Row r=addRow();
00853       row(r,l,e,u);
00854       return r;
00855     }
00856 
00858 
00861     Row addRow(const Constr &c) {
00862       Row r=addRow();
00863       row(r,c);
00864       return r;
00865     }
00867 
00870     void eraseCol(Col c) {
00871       _eraseCol(cols.floatingId(c.id));
00872       cols.erase(c.id);
00873     }
00875 
00878     void eraseRow(Row r) {
00879       _eraseRow(rows.floatingId(r.id));
00880       rows.erase(r.id);
00881     }
00882 
00884     
00887     std::string ColName(Col c){
00888       std::string name;
00889       _getColName(cols.floatingId(c.id), name);
00890       return name;
00891     }
00892     
00894     
00897     void ColName(Col c, const std::string & name){
00898       _setColName(cols.floatingId(c.id), name);
00899     }
00900     
00902 
00906 
00907     void Coeff(Row r, Col c, Value val){
00908       _setCoeff(rows.floatingId(r.id),cols.floatingId(c.id), val);
00909     }
00910 
00912 
00916     void colLowerBound(Col c, Value value) {
00917       _setColLowerBound(cols.floatingId(c.id),value);
00918     }
00919     
00928 #ifdef DOXYGEN
00929     template<class T>
00930     void colLowerBound(T &t, Value value) { return 0;} 
00931 #else
00932     template<class T>
00933     typename enable_if<typename T::value_type::LpSolverCol,void>::type
00934     colLowerBound(T &t, Value value,dummy<0> = 0) {
00935       for(typename T::iterator i=t.begin();i!=t.end();++i) {
00936         colLowerBound(*i, value);
00937       }
00938     }
00939     template<class T>
00940     typename enable_if<typename T::value_type::second_type::LpSolverCol,
00941                        void>::type
00942     colLowerBound(T &t, Value value,dummy<1> = 1) { 
00943       for(typename T::iterator i=t.begin();i!=t.end();++i) {
00944         colLowerBound(i->second, value);
00945       }
00946     }
00947     template<class T>
00948     typename enable_if<typename T::MapIt::Value::LpSolverCol,
00949                        void>::type
00950     colLowerBound(T &t, Value value,dummy<2> = 2) { 
00951       for(typename T::MapIt i(t); i!=INVALID; ++i){
00952         colLowerBound(*i, value);
00953       }
00954     }
00955 #endif
00956     
00958 
00962     void colUpperBound(Col c, Value value) {
00963       _setColUpperBound(cols.floatingId(c.id),value);
00964     };
00965 
00974 #ifdef DOXYGEN
00975     template<class T>
00976     void colUpperBound(T &t, Value value) { return 0;} 
00977 #else
00978     template<class T>
00979     typename enable_if<typename T::value_type::LpSolverCol,void>::type
00980     colUpperBound(T &t, Value value,dummy<0> = 0) {
00981       for(typename T::iterator i=t.begin();i!=t.end();++i) {
00982         colUpperBound(*i, value);
00983       }
00984     }
00985     template<class T>
00986     typename enable_if<typename T::value_type::second_type::LpSolverCol,
00987                        void>::type
00988     colUpperBound(T &t, Value value,dummy<1> = 1) { 
00989       for(typename T::iterator i=t.begin();i!=t.end();++i) {
00990         colUpperBound(i->second, value);
00991       }
00992     }
00993     template<class T>
00994     typename enable_if<typename T::MapIt::Value::LpSolverCol,
00995                        void>::type
00996     colUpperBound(T &t, Value value,dummy<2> = 2) { 
00997       for(typename T::MapIt i(t); i!=INVALID; ++i){
00998         colUpperBound(*i, value);
00999       }
01000     }
01001 #endif
01002 
01004 
01009     void colBounds(Col c, Value lower, Value upper) {
01010       _setColLowerBound(cols.floatingId(c.id),lower);
01011       _setColUpperBound(cols.floatingId(c.id),upper);
01012     }
01013     
01023 #ifdef DOXYGEN
01024     template<class T>
01025     void colBounds(T &t, Value lower, Value upper) { return 0;} 
01026 #else
01027     template<class T>
01028     typename enable_if<typename T::value_type::LpSolverCol,void>::type
01029     colBounds(T &t, Value lower, Value upper,dummy<0> = 0) {
01030       for(typename T::iterator i=t.begin();i!=t.end();++i) {
01031         colBounds(*i, lower, upper);
01032       }
01033     }
01034     template<class T>
01035     typename enable_if<typename T::value_type::second_type::LpSolverCol,
01036                        void>::type
01037     colBounds(T &t, Value lower, Value upper,dummy<1> = 1) { 
01038       for(typename T::iterator i=t.begin();i!=t.end();++i) {
01039         colBounds(i->second, lower, upper);
01040       }
01041     }
01042     template<class T>
01043     typename enable_if<typename T::MapIt::Value::LpSolverCol,
01044                        void>::type
01045     colBounds(T &t, Value lower, Value upper,dummy<2> = 2) { 
01046       for(typename T::MapIt i(t); i!=INVALID; ++i){
01047         colBounds(*i, lower, upper);
01048       }
01049     }
01050 #endif
01051     
01052 //     /// Set the lower bound of a row (i.e a constraint)
01053 
01054 //     /// The lower bound of a linear expression (row) has to be given by an 
01055 //     /// extended number of type Value, i.e. a finite number of type 
01056 //     /// Value or -\ref INF.
01057 //     void rowLowerBound(Row r, Value value) {
01058 //       _setRowLowerBound(rows.floatingId(r.id),value);
01059 //     };
01060 //     /// Set the upper bound of a row (i.e a constraint)
01061 
01062 //     /// The upper bound of a linear expression (row) has to be given by an 
01063 //     /// extended number of type Value, i.e. a finite number of type 
01064 //     /// Value or \ref INF.
01065 //     void rowUpperBound(Row r, Value value) {
01066 //       _setRowUpperBound(rows.floatingId(r.id),value);
01067 //     };
01068 
01070 
01075     void rowBounds(Row c, Value lower, Value upper) {
01076       _setRowBounds(rows.floatingId(c.id),lower, upper);
01077       // _setRowUpperBound(rows.floatingId(c.id),upper);
01078     }
01079     
01081     void objCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); };
01083     
01086     void setObj(Expr e) {
01087       _clearObj();
01088       for (Expr::iterator i=e.begin(); i!=e.end(); ++i)
01089         objCoeff((*i).first,(*i).second);
01090       obj_const_comp=e.constComp();
01091     }
01092 
01094     void max() { _setMax(); }
01096     void min() { _setMin(); }
01097 
01098     
01100 
01101 
01103 
01105 
01111     SolveExitStatus solve() { return _solve(); }
01112     
01114     
01116 
01118 
01120     SolutionStatus primalStatus() {
01121       return _getPrimalStatus();
01122     }
01123 
01125     SolutionStatus dualStatus() {
01126       return _getDualStatus();
01127     }
01128 
01130     ProblemTypes problemType() {
01131       return _getProblemType();
01132     }
01133 
01135     Value primal(Col c) { return _getPrimal(cols.floatingId(c.id)); }
01136 
01138     Value dual(Row r) { return _getDual(rows.floatingId(r.id)); }
01139 
01141     bool isBasicCol(Col c) { return _isBasicCol(cols.floatingId(c.id)); }
01142 
01144 
01150     Value primalValue() { return _getPrimalValue()+obj_const_comp;}
01152     
01153   };  
01154 
01156   
01159   inline LpSolverBase::Expr operator+(const LpSolverBase::Expr &a,
01160                                       const LpSolverBase::Expr &b) 
01161   {
01162     LpSolverBase::Expr tmp(a);
01163     tmp+=b;
01164     return tmp;
01165   }
01167   
01170   inline LpSolverBase::Expr operator-(const LpSolverBase::Expr &a,
01171                                       const LpSolverBase::Expr &b) 
01172   {
01173     LpSolverBase::Expr tmp(a);
01174     tmp-=b;
01175     return tmp;
01176   }
01178   
01181   inline LpSolverBase::Expr operator*(const LpSolverBase::Expr &a,
01182                                       const LpSolverBase::Value &b) 
01183   {
01184     LpSolverBase::Expr tmp(a);
01185     tmp*=b;
01186     return tmp;
01187   }
01188   
01190   
01193   inline LpSolverBase::Expr operator*(const LpSolverBase::Value &a,
01194                                       const LpSolverBase::Expr &b) 
01195   {
01196     LpSolverBase::Expr tmp(b);
01197     tmp*=a;
01198     return tmp;
01199   }
01201   
01204   inline LpSolverBase::Expr operator/(const LpSolverBase::Expr &a,
01205                                       const LpSolverBase::Value &b) 
01206   {
01207     LpSolverBase::Expr tmp(a);
01208     tmp/=b;
01209     return tmp;
01210   }
01211   
01213   
01216   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
01217                                          const LpSolverBase::Expr &f) 
01218   {
01219     return LpSolverBase::Constr(-LpSolverBase::INF,e-f,0);
01220   }
01221 
01223   
01226   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &e,
01227                                          const LpSolverBase::Expr &f) 
01228   {
01229     return LpSolverBase::Constr(e,f);
01230   }
01231 
01233   
01236   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
01237                                          const LpSolverBase::Value &f) 
01238   {
01239     return LpSolverBase::Constr(e,f);
01240   }
01241 
01243   
01246   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
01247                                          const LpSolverBase::Expr &f) 
01248   {
01249     return LpSolverBase::Constr(-LpSolverBase::INF,f-e,0);
01250   }
01251 
01252 
01254   
01257   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &e,
01258                                          const LpSolverBase::Expr &f) 
01259   {
01260     return LpSolverBase::Constr(f,e);
01261   }
01262 
01263 
01265   
01268   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
01269                                          const LpSolverBase::Value &f) 
01270   {
01271     return LpSolverBase::Constr(f,e);
01272   }
01273 
01275   
01278   inline LpSolverBase::Constr operator==(const LpSolverBase::Expr &e,
01279                                          const LpSolverBase::Expr &f) 
01280   {
01281     return LpSolverBase::Constr(0,e-f,0);
01282   }
01283 
01285   
01288   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &n,
01289                                          const LpSolverBase::Constr&c) 
01290   {
01291     LpSolverBase::Constr tmp(c);
01293     if(!isnan(tmp.lowerBound())) throw LogicError();
01294     else tmp.lowerBound()=n;
01295     return tmp;
01296   }
01298   
01301   inline LpSolverBase::Constr operator<=(const LpSolverBase::Constr& c,
01302                                          const LpSolverBase::Value &n)
01303   {
01304     LpSolverBase::Constr tmp(c);
01306     if(!isnan(tmp.upperBound())) throw LogicError();
01307     else tmp.upperBound()=n;
01308     return tmp;
01309   }
01310 
01312   
01315   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &n,
01316                                          const LpSolverBase::Constr&c) 
01317   {
01318     LpSolverBase::Constr tmp(c);
01320     if(!isnan(tmp.upperBound())) throw LogicError();
01321     else tmp.upperBound()=n;
01322     return tmp;
01323   }
01325   
01328   inline LpSolverBase::Constr operator>=(const LpSolverBase::Constr& c,
01329                                          const LpSolverBase::Value &n)
01330   {
01331     LpSolverBase::Constr tmp(c);
01333     if(!isnan(tmp.lowerBound())) throw LogicError();
01334     else tmp.lowerBound()=n;
01335     return tmp;
01336   }
01337 
01339   
01342   inline LpSolverBase::DualExpr operator+(const LpSolverBase::DualExpr &a,
01343                                       const LpSolverBase::DualExpr &b) 
01344   {
01345     LpSolverBase::DualExpr tmp(a);
01346     tmp+=b;
01347     return tmp;
01348   }
01350   
01353   inline LpSolverBase::DualExpr operator-(const LpSolverBase::DualExpr &a,
01354                                       const LpSolverBase::DualExpr &b) 
01355   {
01356     LpSolverBase::DualExpr tmp(a);
01357     tmp-=b;
01358     return tmp;
01359   }
01361   
01364   inline LpSolverBase::DualExpr operator*(const LpSolverBase::DualExpr &a,
01365                                       const LpSolverBase::Value &b) 
01366   {
01367     LpSolverBase::DualExpr tmp(a);
01368     tmp*=b;
01369     return tmp;
01370   }
01371   
01373   
01376   inline LpSolverBase::DualExpr operator*(const LpSolverBase::Value &a,
01377                                       const LpSolverBase::DualExpr &b) 
01378   {
01379     LpSolverBase::DualExpr tmp(b);
01380     tmp*=a;
01381     return tmp;
01382   }
01384   
01387   inline LpSolverBase::DualExpr operator/(const LpSolverBase::DualExpr &a,
01388                                       const LpSolverBase::Value &b) 
01389   {
01390     LpSolverBase::DualExpr tmp(a);
01391     tmp/=b;
01392     return tmp;
01393   }
01394   
01395 
01396 } //namespace lemon
01397 
01398 #endif //LEMON_LP_BASE_H

Generated on Fri Feb 3 18:38:42 2006 for LEMON by  doxygen 1.4.6