[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 |
---|