# HG changeset patch # User alpar # Date 1111755532 0 # Node ID 11a09f1319b372d432f9ded505f9289d9b3ae0c9 # Parent 88dff8bb4bf23cfcd3372c57415cdf11671ef70e - Largely extended linear expressions - Better docs diff -r 88dff8bb4bf2 -r 11a09f1319b3 src/work/athos/lp/lin_expr.h --- a/src/work/athos/lp/lin_expr.h Fri Mar 25 11:03:49 2005 +0000 +++ b/src/work/athos/lp/lin_expr.h Fri Mar 25 12:58:52 2005 +0000 @@ -27,31 +27,37 @@ namespace lemon { /// Class to handle sparse linear expressions - template - class SparseLinExpr : public std::map<_V, _C> + template + class SparseLinExpr : public std::map<_V, typename _V::ExprValue> { public: typedef _V Var; - typedef _C Coeff; + typedef typename _V::ExprValue Coeff; protected: - typedef typename std::map<_V, _C> Base; + typedef typename std::map<_V, typename _V::ExprValue> Base; Coeff const_comp; public: - SparseLinExpr() { } - SparseLinExpr(const Var &v) : const_comp(v) { + ///\e + SparseLinExpr() : Base(), const_comp(0) { } + ///\e + SparseLinExpr(const Var &v) : const_comp(0) { Base::insert(std::make_pair(v, 1)); } + ///\e SparseLinExpr(const Coeff &v) : const_comp(v) {} + ///\e void set(const Var &v,const Coeff &c) { return Base::insert(std::make_pair(v, c)); } // Coeff &operator[](const Var &v) { return data[v]; } // const Coeff &operator[](const Var &v) const { return data[v]; } + ///\e Coeff &constComp() { return const_comp; } + ///\e const Coeff &constComp() const { return const_comp; } ///Removes the components with zero coefficient. @@ -64,8 +70,238 @@ } } + ///\e + SparseLinExpr &operator+=(const SparseLinExpr &e) { + for (typename Base::const_iterator j=e.begin(); j!=e.end(); ++j) + (*this)[j->first]+=j->second; + ///\todo it might be speeded up using "hints" + const_comp+=e.const_comp; + return *this; + } + ///\e + SparseLinExpr &operator-=(const SparseLinExpr &e) { + for (typename Base::const_iterator j=e.begin(); j!=e.end(); ++j) + (*this)[j->first]-=j->second; + const_comp-=e.const_comp; + return *this; + } + ///\e + SparseLinExpr &operator*=(const Coeff &c) { + for (typename Base::iterator j=Base::begin(); j!=Base::end(); ++j) + j->second*=c; + const_comp*=c; + return *this; + } + ///\e + SparseLinExpr &operator/=(const Coeff &c) { + for (typename Base::iterator j=Base::begin(); j!=Base::end(); ++j) + j->second/=c; + const_comp/=c; + return *this; + } + }; + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator+(const SparseLinExpr &a, + const SparseLinExpr &b) { + SparseLinExpr tmp(a); + tmp+=b; ///\todo Don't STL have some special 'merge' algorithm? + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator-(const SparseLinExpr &a, + const SparseLinExpr &b) { + SparseLinExpr tmp(a); + tmp-=b; ///\todo Don't STL have some special 'merge' algorithm? + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator*(const typename V::ExprValue &c, + const SparseLinExpr &e) { + SparseLinExpr tmp(e); + tmp*=c; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator*(const SparseLinExpr &e, + const typename V::ExprValue &c) { + SparseLinExpr tmp(e); + tmp*=c; + return tmp; + } + + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator/(const SparseLinExpr &e, + const typename V::ExprValue &c) { + SparseLinExpr tmp(e); + tmp/=c; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator+(const typename V::ExprValue &c, + const SparseLinExpr &e) { + SparseLinExpr tmp(e); + tmp.constComp()+=c; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator+(const SparseLinExpr &e, + const typename V::ExprValue &c) { + SparseLinExpr tmp(e); + tmp.constComp()+=c; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator+(const V &v,const SparseLinExpr &e) { + SparseLinExpr tmp(e); + tmp[v]+=1; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator+(const SparseLinExpr &e,const V &v) { + SparseLinExpr tmp(e); + tmp[v]+=1; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator-(const typename V::ExprValue &c, + const SparseLinExpr &e) { + SparseLinExpr tmp(e); + tmp*=-1; + tmp.constComp()+=c; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator-(const SparseLinExpr &e, + const typename V::ExprValue &c) { + SparseLinExpr tmp(e); + tmp.constComp()-=c; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator-(const V &v,const SparseLinExpr &e) { + SparseLinExpr tmp(e); + tmp*=-1; + tmp[v]+=1; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator-(const SparseLinExpr &e,const V &v) { + SparseLinExpr tmp(e); + tmp[v]-=1; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator+(const V &v1,const V &v2) { + SparseLinExpr tmp(v1); + tmp[v2]+=1; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator*(const V &v,const typename V::ExprValue &c) { + SparseLinExpr tmp; + tmp[v]=c; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator*(const typename V::ExprValue &c,const V &v) { + SparseLinExpr tmp; + tmp[v]=c; + return tmp; + } + + ///\e + + ///\relates SparseLinExpr + /// + template + SparseLinExpr operator/(const V &v,const typename V::ExprValue &c) { + SparseLinExpr tmp; + tmp[v]=1/c; + return tmp; + } + + } //namespace lemon #endif //LEMON_LIN_EXPR_H diff -r 88dff8bb4bf2 -r 11a09f1319b3 src/work/athos/lp/lp_base.h --- a/src/work/athos/lp/lp_base.h Fri Mar 25 11:03:49 2005 +0000 +++ b/src/work/athos/lp/lp_base.h Fri Mar 25 12:58:52 2005 +0000 @@ -120,6 +120,7 @@ int id; friend class LpSolverBase; public: + typedef Value ExprValue; typedef True LpSolverCol; Col() {} Col(const Invalid&) : id(-1) {} @@ -142,6 +143,7 @@ int id; friend class LpSolverBase; public: + typedef Value ExprValue; typedef True LpSolverRow; Row() {} Row(const Invalid&) : id(-1) {} @@ -150,8 +152,9 @@ bool operator==(Row c) const {return id==c.id;} bool operator!=(Row c) const {return id==c.id;} }; - - typedef SparseLinExpr Expr; + + ///Linear expression + typedef SparseLinExpr Expr; protected: _FixId rows; @@ -184,25 +187,25 @@ /// The lower bound of a variable (column) have to be given by an /// extended number of type Value, i.e. a finite number of type - /// Value or -INF. + /// Value or -\ref INF. virtual void _setColLowerBound(int i, Value value) = 0; /// \e /// The upper bound of a variable (column) have to be given by an /// extended number of type Value, i.e. a finite number of type - /// Value or INF. + /// Value or \ref INF. virtual void _setColUpperBound(int i, Value value) = 0; /// \e /// The lower bound of a linear expression (row) have to be given by an /// extended number of type Value, i.e. a finite number of type - /// Value or -INF. + /// Value or -\ref INF. virtual void _setRowLowerBound(int i, Value value) = 0; /// \e /// The upper bound of a linear expression (row) have to be given by an /// extended number of type Value, i.e. a finite number of type - /// Value or INF. + /// Value or \ref INF. virtual void _setRowUpperBound(int i, Value value) = 0; /// \e @@ -267,9 +270,9 @@ ///Set a row (i.e a constaint) of the LP ///\param r is the row to be modified - ///\param l is lower bound (-INF means no bound) + ///\param l is lower bound (-\ref INF means no bound) ///\param e is a linear expression (see \ref Expr) - ///\param u is the upper bound (INF means no bound) + ///\param u is the upper bound (\ref INF means no bound) ///\bug This is a temportary function. The interface will change to ///a better one. void setRow(Row r, Value l,const Expr &e, Value u) { @@ -290,9 +293,9 @@ ///Add a new row (i.e a new constaint) to the LP - ///\param l is the lower bound (-INF means no bound) + ///\param l is the lower bound (-\ref INF means no bound) ///\param e is a linear expression (see \ref Expr) - ///\param u is the upper bound (INF means no bound) + ///\param u is the upper bound (\ref INF means no bound) ///\return The created row. ///\bug This is a temportary function. The interface will change to ///a better one. @@ -306,7 +309,7 @@ /// The upper bound of a variable (column) have to be given by an /// extended number of type Value, i.e. a finite number of type - /// Value or -INF. + /// Value or -\ref INF. virtual void setColLowerBound(Col c, Value value) { _setColLowerBound(cols.floatingId(c.id),value); } @@ -314,7 +317,7 @@ /// The upper bound of a variable (column) have to be given by an /// extended number of type Value, i.e. a finite number of type - /// Value or INF. + /// Value or \ref INF. virtual void setColUpperBound(Col c, Value value) { _setColUpperBound(cols.floatingId(c.id),value); }; @@ -322,7 +325,7 @@ /// The lower bound of a linear expression (row) have to be given by an /// extended number of type Value, i.e. a finite number of type - /// Value or -INF. + /// Value or -\ref INF. virtual void setRowLowerBound(Row r, Value value) { _setRowLowerBound(rows.floatingId(r.id),value); }; @@ -330,7 +333,7 @@ /// The upper bound of a linear expression (row) have to be given by an /// extended number of type Value, i.e. a finite number of type - /// Value or INF. + /// Value or \ref INF. virtual void setRowUpperBound(Row r, Value value) { _setRowUpperBound(rows.floatingId(r.id),value); }; diff -r 88dff8bb4bf2 -r 11a09f1319b3 src/work/athos/lp/lp_test.cc --- a/src/work/athos/lp/lp_test.cc Fri Mar 25 11:03:49 2005 +0000 +++ b/src/work/athos/lp/lp_test.cc Fri Mar 25 12:58:52 2005 +0000 @@ -28,6 +28,12 @@ e[x[3]]=4; e[x[3]]=1; e.constComp()=12; + + LP::Col p1,p2,p3,p4,p5; + lp.addRow(LP::INF,e,23); - + lp.addRow(LP::INF,3.0*(p1+p2)-p3,23); + lp.addRow(LP::INF,3.0*(x[1]+x[2]/2)-x[3],23); + lp.addRow(LP::INF,3.0*(p1+p2*2-5*p3+12-p4/3)+2*p4-4,23); + lp.addRow(LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23); }