alpar@1253: /* -*- C++ -*- alpar@1253: * src/lemon/lin_expr.h - Part of LEMON, a generic C++ optimization library alpar@1253: * alpar@1253: * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@1253: * (Egervary Combinatorial Optimization Research Group, EGRES). alpar@1253: * alpar@1253: * Permission to use, modify and distribute this software is granted alpar@1253: * provided that this copyright notice appears in all copies. For alpar@1253: * precise terms see the accompanying LICENSE file. alpar@1253: * alpar@1253: * This software is provided "AS IS" with no warranty of any kind, alpar@1253: * express or implied, and with no claim as to its suitability for any alpar@1253: * purpose. alpar@1253: * alpar@1253: */ alpar@1253: alpar@1253: #ifndef LEMON_LIN_EXPR_H alpar@1253: #define LEMON_LIN_EXPR_H alpar@1253: alpar@1253: #include alpar@1253: alpar@1253: alpar@1253: #include alpar@1253: alpar@1253: ///\file alpar@1253: ///\brief Classes to handle linear expressions alpar@1253: namespace lemon { alpar@1253: alpar@1253: /// Class to handle sparse linear expressions alpar@1259: template alpar@1259: class SparseLinExpr : public std::map<_V, typename _V::ExprValue> alpar@1253: { alpar@1253: public: alpar@1253: typedef _V Var; alpar@1259: typedef typename _V::ExprValue Coeff; alpar@1253: alpar@1253: protected: alpar@1259: typedef typename std::map<_V, typename _V::ExprValue> Base; alpar@1253: alpar@1253: Coeff const_comp; alpar@1253: public: alpar@1259: ///\e alpar@1259: SparseLinExpr() : Base(), const_comp(0) { } alpar@1259: ///\e alpar@1259: SparseLinExpr(const Var &v) : const_comp(0) { alpar@1253: Base::insert(std::make_pair(v, 1)); alpar@1253: } alpar@1259: ///\e alpar@1253: SparseLinExpr(const Coeff &v) : const_comp(v) {} alpar@1253: alpar@1259: ///\e alpar@1253: void set(const Var &v,const Coeff &c) { alpar@1253: return Base::insert(std::make_pair(v, c)); alpar@1253: } alpar@1253: // Coeff &operator[](const Var &v) { return data[v]; } alpar@1253: // const Coeff &operator[](const Var &v) const { return data[v]; } alpar@1253: alpar@1259: ///\e alpar@1253: Coeff &constComp() { return const_comp; } alpar@1259: ///\e alpar@1253: const Coeff &constComp() const { return const_comp; } alpar@1253: alpar@1253: ///Removes the components with zero coefficient. alpar@1253: void simplify() { alpar@1253: for (typename Base::iterator i=Base::begin(); i!=Base::end();) { alpar@1253: typename Base::iterator j=i; alpar@1253: ++j; alpar@1253: if ((*i).second==0) Base::erase(i); alpar@1253: j=i; alpar@1253: } alpar@1253: } alpar@1253: alpar@1259: ///\e alpar@1259: SparseLinExpr &operator+=(const SparseLinExpr &e) { alpar@1259: for (typename Base::const_iterator j=e.begin(); j!=e.end(); ++j) alpar@1259: (*this)[j->first]+=j->second; alpar@1259: ///\todo it might be speeded up using "hints" alpar@1259: const_comp+=e.const_comp; alpar@1259: return *this; alpar@1259: } alpar@1259: ///\e alpar@1259: SparseLinExpr &operator-=(const SparseLinExpr &e) { alpar@1259: for (typename Base::const_iterator j=e.begin(); j!=e.end(); ++j) alpar@1259: (*this)[j->first]-=j->second; alpar@1259: const_comp-=e.const_comp; alpar@1259: return *this; alpar@1259: } alpar@1259: ///\e alpar@1259: SparseLinExpr &operator*=(const Coeff &c) { alpar@1259: for (typename Base::iterator j=Base::begin(); j!=Base::end(); ++j) alpar@1259: j->second*=c; alpar@1259: const_comp*=c; alpar@1259: return *this; alpar@1259: } alpar@1259: ///\e alpar@1259: SparseLinExpr &operator/=(const Coeff &c) { alpar@1259: for (typename Base::iterator j=Base::begin(); j!=Base::end(); ++j) alpar@1259: j->second/=c; alpar@1259: const_comp/=c; alpar@1259: return *this; alpar@1259: } alpar@1259: alpar@1253: }; alpar@1253: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator+(const SparseLinExpr &a, alpar@1259: const SparseLinExpr &b) { alpar@1259: SparseLinExpr tmp(a); alpar@1259: tmp+=b; ///\todo Don't STL have some special 'merge' algorithm? alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator-(const SparseLinExpr &a, alpar@1259: const SparseLinExpr &b) { alpar@1259: SparseLinExpr tmp(a); alpar@1259: tmp-=b; ///\todo Don't STL have some special 'merge' algorithm? alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator*(const typename V::ExprValue &c, alpar@1259: const SparseLinExpr &e) { alpar@1259: SparseLinExpr tmp(e); alpar@1259: tmp*=c; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator*(const SparseLinExpr &e, alpar@1259: const typename V::ExprValue &c) { alpar@1259: SparseLinExpr tmp(e); alpar@1259: tmp*=c; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator/(const SparseLinExpr &e, alpar@1259: const typename V::ExprValue &c) { alpar@1259: SparseLinExpr tmp(e); alpar@1259: tmp/=c; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator+(const typename V::ExprValue &c, alpar@1259: const SparseLinExpr &e) { alpar@1259: SparseLinExpr tmp(e); alpar@1259: tmp.constComp()+=c; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator+(const SparseLinExpr &e, alpar@1259: const typename V::ExprValue &c) { alpar@1259: SparseLinExpr tmp(e); alpar@1259: tmp.constComp()+=c; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator+(const V &v,const SparseLinExpr &e) { alpar@1259: SparseLinExpr tmp(e); alpar@1259: tmp[v]+=1; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator+(const SparseLinExpr &e,const V &v) { alpar@1259: SparseLinExpr tmp(e); alpar@1259: tmp[v]+=1; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator-(const typename V::ExprValue &c, alpar@1259: const SparseLinExpr &e) { alpar@1259: SparseLinExpr tmp(e); alpar@1259: tmp*=-1; alpar@1259: tmp.constComp()+=c; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator-(const SparseLinExpr &e, alpar@1259: const typename V::ExprValue &c) { alpar@1259: SparseLinExpr tmp(e); alpar@1259: tmp.constComp()-=c; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator-(const V &v,const SparseLinExpr &e) { alpar@1259: SparseLinExpr tmp(e); alpar@1259: tmp*=-1; alpar@1259: tmp[v]+=1; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator-(const SparseLinExpr &e,const V &v) { alpar@1259: SparseLinExpr tmp(e); alpar@1259: tmp[v]-=1; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator+(const V &v1,const V &v2) { alpar@1259: SparseLinExpr tmp(v1); alpar@1259: tmp[v2]+=1; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator*(const V &v,const typename V::ExprValue &c) { alpar@1259: SparseLinExpr tmp; alpar@1259: tmp[v]=c; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator*(const typename V::ExprValue &c,const V &v) { alpar@1259: SparseLinExpr tmp; alpar@1259: tmp[v]=c; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: ///\e alpar@1259: alpar@1259: ///\relates SparseLinExpr alpar@1259: /// alpar@1259: template alpar@1259: SparseLinExpr operator/(const V &v,const typename V::ExprValue &c) { alpar@1259: SparseLinExpr tmp; alpar@1259: tmp[v]=1/c; alpar@1259: return tmp; alpar@1259: } alpar@1259: alpar@1259: alpar@1253: } //namespace lemon alpar@1253: alpar@1253: #endif //LEMON_LIN_EXPR_H