| [1097] | 1 | // -*- c++ -*- | 
|---|
|  | 2 | #ifndef LEMON_EXPRESSION_H | 
|---|
|  | 3 | #define LEMON_EXPRESSION_H | 
|---|
|  | 4 |  | 
|---|
|  | 5 | #include <iostream> | 
|---|
|  | 6 | #include <map> | 
|---|
| [1144] | 7 | #include <limits> | 
|---|
| [1097] | 8 |  | 
|---|
|  | 9 | namespace lemon { | 
|---|
|  | 10 |  | 
|---|
|  | 11 | /*! \brief Linear expression | 
|---|
|  | 12 |  | 
|---|
|  | 13 | \c Expr<_Col,_Value> implements a class of linear expressions with the | 
|---|
|  | 14 | operations of addition and multiplication with scalar. | 
|---|
|  | 15 |  | 
|---|
|  | 16 | \author Marton Makai | 
|---|
|  | 17 | */ | 
|---|
|  | 18 | template <typename _Col, typename _Value> | 
|---|
|  | 19 | class Expr; | 
|---|
|  | 20 |  | 
|---|
|  | 21 | template <typename _Col, typename _Value> | 
|---|
|  | 22 | class Expr { | 
|---|
| [1099] | 23 | //  protected: | 
|---|
|  | 24 | public: | 
|---|
| [1097] | 25 | typedef | 
|---|
|  | 26 | typename std::map<_Col, _Value> Data; | 
|---|
|  | 27 | Data data; | 
|---|
|  | 28 | public: | 
|---|
| [1099] | 29 | void simplify() { | 
|---|
|  | 30 | for (typename Data::iterator i=data.begin(); | 
|---|
|  | 31 | i!=data.end(); ++i) { | 
|---|
|  | 32 | if ((*i).second==0) data.erase(i); | 
|---|
|  | 33 | } | 
|---|
|  | 34 | } | 
|---|
| [1097] | 35 | Expr() { } | 
|---|
|  | 36 | Expr(_Col _col) { | 
|---|
|  | 37 | data.insert(std::make_pair(_col, 1)); | 
|---|
|  | 38 | } | 
|---|
|  | 39 | Expr& operator*=(_Value _value) { | 
|---|
|  | 40 | for (typename Data::iterator i=data.begin(); | 
|---|
|  | 41 | i!=data.end(); ++i) { | 
|---|
|  | 42 | (*i).second *= _value; | 
|---|
|  | 43 | } | 
|---|
| [1099] | 44 | simplify(); | 
|---|
| [1097] | 45 | return *this; | 
|---|
|  | 46 | } | 
|---|
|  | 47 | Expr& operator+=(const Expr<_Col, _Value>& expr) { | 
|---|
|  | 48 | for (typename Data::const_iterator j=expr.data.begin(); | 
|---|
|  | 49 | j!=expr.data.end(); ++j) { | 
|---|
|  | 50 | typename Data::iterator i=data.find((*j).first); | 
|---|
|  | 51 | if (i==data.end()) { | 
|---|
|  | 52 | data.insert(std::make_pair((*j).first, (*j).second)); | 
|---|
|  | 53 | } else { | 
|---|
|  | 54 | (*i).second+=(*j).second; | 
|---|
|  | 55 | } | 
|---|
|  | 56 | } | 
|---|
| [1099] | 57 | simplify(); | 
|---|
|  | 58 | return *this; | 
|---|
|  | 59 | } | 
|---|
|  | 60 | Expr& operator-=(const Expr<_Col, _Value>& expr) { | 
|---|
|  | 61 | for (typename Data::const_iterator j=expr.data.begin(); | 
|---|
|  | 62 | j!=expr.data.end(); ++j) { | 
|---|
|  | 63 | typename Data::iterator i=data.find((*j).first); | 
|---|
|  | 64 | if (i==data.end()) { | 
|---|
|  | 65 | data.insert(std::make_pair((*j).first, -(*j).second)); | 
|---|
|  | 66 | } else { | 
|---|
|  | 67 | (*i).second+=-(*j).second; | 
|---|
|  | 68 | } | 
|---|
|  | 69 | } | 
|---|
|  | 70 | simplify(); | 
|---|
| [1097] | 71 | return *this; | 
|---|
|  | 72 | } | 
|---|
|  | 73 | template <typename _C, typename _V> | 
|---|
|  | 74 | friend std::ostream& operator<<(std::ostream& os, | 
|---|
|  | 75 | const Expr<_C, _V>& expr); | 
|---|
|  | 76 | }; | 
|---|
|  | 77 |  | 
|---|
|  | 78 | template <typename _Col, typename _Value> | 
|---|
|  | 79 | Expr<_Col, _Value> operator*(_Value _value, _Col _col) { | 
|---|
|  | 80 | Expr<_Col, _Value> tmp(_col); | 
|---|
|  | 81 | tmp*=_value; | 
|---|
| [1099] | 82 | tmp.simplify(); | 
|---|
| [1097] | 83 | return tmp; | 
|---|
|  | 84 | } | 
|---|
|  | 85 |  | 
|---|
|  | 86 | template <typename _Col, typename _Value> | 
|---|
|  | 87 | Expr<_Col, _Value> operator*(_Value _value, | 
|---|
|  | 88 | const Expr<_Col, _Value>& expr) { | 
|---|
|  | 89 | Expr<_Col, _Value> tmp(expr); | 
|---|
|  | 90 | tmp*=_value; | 
|---|
| [1099] | 91 | tmp.simplify(); | 
|---|
| [1097] | 92 | return tmp; | 
|---|
|  | 93 | } | 
|---|
|  | 94 |  | 
|---|
|  | 95 | template <typename _Col, typename _Value> | 
|---|
|  | 96 | Expr<_Col, _Value> operator+(const Expr<_Col, _Value>& expr1, | 
|---|
|  | 97 | const Expr<_Col, _Value>& expr2) { | 
|---|
|  | 98 | Expr<_Col, _Value> tmp(expr1); | 
|---|
|  | 99 | tmp+=expr2; | 
|---|
| [1099] | 100 | tmp.simplify(); | 
|---|
|  | 101 | return tmp; | 
|---|
|  | 102 | } | 
|---|
|  | 103 |  | 
|---|
|  | 104 | template <typename _Col, typename _Value> | 
|---|
|  | 105 | Expr<_Col, _Value> operator-(const Expr<_Col, _Value>& expr1, | 
|---|
|  | 106 | const Expr<_Col, _Value>& expr2) { | 
|---|
|  | 107 | Expr<_Col, _Value> tmp(expr1); | 
|---|
|  | 108 | tmp-=expr2; | 
|---|
|  | 109 | tmp.simplify(); | 
|---|
| [1097] | 110 | return tmp; | 
|---|
|  | 111 | } | 
|---|
|  | 112 |  | 
|---|
|  | 113 | template <typename _Col, typename _Value> | 
|---|
|  | 114 | std::ostream& operator<<(std::ostream& os, | 
|---|
|  | 115 | const Expr<_Col, _Value>& expr) { | 
|---|
|  | 116 | for (typename Expr<_Col, _Value>::Data::const_iterator i= | 
|---|
|  | 117 | expr.data.begin(); | 
|---|
|  | 118 | i!=expr.data.end(); ++i) { | 
|---|
|  | 119 | os << (*i).second << "*" << (*i).first << " "; | 
|---|
|  | 120 | } | 
|---|
|  | 121 | return os; | 
|---|
|  | 122 | } | 
|---|
| [1144] | 123 |  | 
|---|
|  | 124 | template <typename _Col, typename _Value> | 
|---|
|  | 125 | class LConstr { | 
|---|
|  | 126 | //  protected: | 
|---|
|  | 127 | public: | 
|---|
|  | 128 | Expr<_Col, _Value> expr; | 
|---|
|  | 129 | _Value lo; | 
|---|
|  | 130 | public: | 
|---|
|  | 131 | LConstr(const Expr<_Col, _Value>& _expr, _Value _lo) : | 
|---|
|  | 132 | expr(_expr), lo(_lo) { } | 
|---|
|  | 133 | }; | 
|---|
|  | 134 |  | 
|---|
|  | 135 | template <typename _Col, typename _Value> | 
|---|
|  | 136 | LConstr<_Col, _Value> | 
|---|
|  | 137 | operator<=(_Value lo, const Expr<_Col, _Value>& expr) { | 
|---|
|  | 138 | return LConstr<_Col, _Value>(expr, lo); | 
|---|
|  | 139 | } | 
|---|
|  | 140 |  | 
|---|
|  | 141 | template <typename _Col, typename _Value> | 
|---|
|  | 142 | class UConstr { | 
|---|
|  | 143 | //  protected: | 
|---|
|  | 144 | public: | 
|---|
|  | 145 | Expr<_Col, _Value> expr; | 
|---|
|  | 146 | _Value up; | 
|---|
|  | 147 | public: | 
|---|
|  | 148 | UConstr(const Expr<_Col, _Value>& _expr, _Value _up) : | 
|---|
|  | 149 | expr(_expr), up(_up) { } | 
|---|
|  | 150 | }; | 
|---|
|  | 151 |  | 
|---|
|  | 152 | template <typename _Col, typename _Value> | 
|---|
|  | 153 | UConstr<_Col, _Value> | 
|---|
|  | 154 | operator<=(const Expr<_Col, _Value>& expr, _Value up) { | 
|---|
|  | 155 | return UConstr<_Col, _Value>(expr, up); | 
|---|
|  | 156 | } | 
|---|
|  | 157 |  | 
|---|
|  | 158 | template <typename _Col, typename _Value> | 
|---|
|  | 159 | class Constr { | 
|---|
|  | 160 | //  protected: | 
|---|
|  | 161 | public: | 
|---|
|  | 162 | Expr<_Col, _Value> expr; | 
|---|
|  | 163 | _Value lo, up; | 
|---|
|  | 164 | public: | 
|---|
|  | 165 | Constr(const Expr<_Col, _Value>& _expr, _Value _lo, _Value _up) : | 
|---|
|  | 166 | expr(_expr), lo(_lo), up(_up) { } | 
|---|
|  | 167 | Constr(const LConstr<_Col, _Value>& _lconstr) : | 
|---|
|  | 168 | expr(_lconstr.expr), | 
|---|
|  | 169 | lo(_lconstr.lo), | 
|---|
|  | 170 | up(std::numeric_limits<_Value>::infinity()) { } | 
|---|
|  | 171 | Constr(const UConstr<_Col, _Value>& _uconstr) : | 
|---|
|  | 172 | expr(_uconstr.expr), | 
|---|
|  | 173 | lo(-std::numeric_limits<_Value>::infinity()), | 
|---|
|  | 174 | up(_uconstr.up) { } | 
|---|
|  | 175 | }; | 
|---|
|  | 176 |  | 
|---|
|  | 177 | template <typename _Col, typename _Value> | 
|---|
|  | 178 | Constr<_Col, _Value> | 
|---|
|  | 179 | operator<=(const LConstr<_Col, _Value>& lconstr, _Value up) { | 
|---|
|  | 180 | return Constr<_Col, _Value>(lconstr.expr, lconstr.lo, up); | 
|---|
|  | 181 | } | 
|---|
|  | 182 |  | 
|---|
|  | 183 | template <typename _Col, typename _Value> | 
|---|
|  | 184 | Constr<_Col, _Value> | 
|---|
|  | 185 | operator<=(_Value lo, const UConstr<_Col, _Value>& uconstr) { | 
|---|
|  | 186 | return Constr<_Col, _Value>(uconstr.expr, lo, uconstr.up); | 
|---|
|  | 187 | } | 
|---|
|  | 188 |  | 
|---|
|  | 189 | template <typename _Col, typename _Value> | 
|---|
|  | 190 | Constr<_Col, _Value> | 
|---|
|  | 191 | operator==(const Expr<_Col, _Value>& expr, _Value value) { | 
|---|
|  | 192 | return Constr<_Col, _Value>(expr, value, value); | 
|---|
|  | 193 | } | 
|---|
| [1097] | 194 |  | 
|---|
|  | 195 | } //namespace lemon | 
|---|
|  | 196 |  | 
|---|
|  | 197 | #endif //LEMON_EXPRESSION_H | 
|---|