2 * src/lemon/lin_expr.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #ifndef LEMON_LIN_EXPR_H
18 #define LEMON_LIN_EXPR_H
22 #include<lemon/utility.h>
24 ///\brief Classes to handle linear expressions
27 /// Class to handle sparse linear expressions
29 class SparseLinExpr : public std::map<_V, typename _V::ExprValue>
33 typedef typename _V::ExprValue Coeff;
36 typedef typename std::map<_V, typename _V::ExprValue> Base;
40 typedef True IsLinExpression;
42 SparseLinExpr() : Base(), const_comp(0) { }
44 SparseLinExpr(const Var &v) : const_comp(0) {
45 Base::insert(std::make_pair(v, 1));
48 SparseLinExpr(const Coeff &v) : const_comp(v) {}
51 void set(const Var &v,const Coeff &c) {
52 return Base::insert(std::make_pair(v, c));
54 // Coeff &operator[](const Var &v) { return data[v]; }
55 // const Coeff &operator[](const Var &v) const { return data[v]; }
58 Coeff &constComp() { return const_comp; }
60 const Coeff &constComp() const { return const_comp; }
62 ///Removes the components with zero coefficient.
64 for (typename Base::iterator i=Base::begin(); i!=Base::end();) {
65 typename Base::iterator j=i;
67 if ((*i).second==0) Base::erase(i);
73 SparseLinExpr &operator+=(const SparseLinExpr &e) {
74 for (typename Base::const_iterator j=e.begin(); j!=e.end(); ++j)
75 (*this)[j->first]+=j->second;
76 ///\todo it might be speeded up using "hints"
77 const_comp+=e.const_comp;
81 SparseLinExpr &operator-=(const SparseLinExpr &e) {
82 for (typename Base::const_iterator j=e.begin(); j!=e.end(); ++j)
83 (*this)[j->first]-=j->second;
84 const_comp-=e.const_comp;
88 SparseLinExpr &operator*=(const Coeff &c) {
89 for (typename Base::iterator j=Base::begin(); j!=Base::end(); ++j)
95 SparseLinExpr &operator/=(const Coeff &c) {
96 for (typename Base::iterator j=Base::begin(); j!=Base::end(); ++j)
106 ///\relates SparseLinExpr
109 SparseLinExpr<V> operator+(const SparseLinExpr<V> &a,
110 const SparseLinExpr<V> &b) {
111 SparseLinExpr<V> tmp(a);
112 tmp+=b; ///\todo Don't STL have some special 'merge' algorithm?
118 ///\relates SparseLinExpr
121 SparseLinExpr<V> operator-(const SparseLinExpr<V> &a,
122 const SparseLinExpr<V> &b) {
123 SparseLinExpr<V> tmp(a);
124 tmp-=b; ///\todo Don't STL have some special 'merge' algorithm?
130 ///\relates SparseLinExpr
133 SparseLinExpr<V> operator*(const typename V::ExprValue &c,
134 const SparseLinExpr<V> &e) {
135 SparseLinExpr<V> tmp(e);
142 ///\relates SparseLinExpr
145 SparseLinExpr<V> operator*(const SparseLinExpr<V> &e,
146 const typename V::ExprValue &c) {
147 SparseLinExpr<V> tmp(e);
155 ///\relates SparseLinExpr
158 SparseLinExpr<V> operator/(const SparseLinExpr<V> &e,
159 const typename V::ExprValue &c) {
160 SparseLinExpr<V> tmp(e);
167 ///\relates SparseLinExpr
170 SparseLinExpr<V> operator+(const typename V::ExprValue &c,
171 const SparseLinExpr<V> &e) {
172 SparseLinExpr<V> tmp(e);
179 ///\relates SparseLinExpr
182 SparseLinExpr<V> operator+(const SparseLinExpr<V> &e,
183 const typename V::ExprValue &c) {
184 SparseLinExpr<V> tmp(e);
191 ///\relates SparseLinExpr
194 SparseLinExpr<V> operator+(const V &v,const SparseLinExpr<V> &e) {
195 SparseLinExpr<V> tmp(e);
202 ///\relates SparseLinExpr
205 SparseLinExpr<V> operator+(const SparseLinExpr<V> &e,const V &v) {
206 SparseLinExpr<V> tmp(e);
213 ///\relates SparseLinExpr
216 SparseLinExpr<V> operator-(const typename V::ExprValue &c,
217 const SparseLinExpr<V> &e) {
218 SparseLinExpr<V> tmp(e);
226 ///\relates SparseLinExpr
229 SparseLinExpr<V> operator-(const SparseLinExpr<V> &e,
230 const typename V::ExprValue &c) {
231 SparseLinExpr<V> tmp(e);
238 ///\relates SparseLinExpr
241 SparseLinExpr<V> operator-(const V &v,const SparseLinExpr<V> &e) {
242 SparseLinExpr<V> tmp(e);
250 ///\relates SparseLinExpr
253 SparseLinExpr<V> operator-(const SparseLinExpr<V> &e,const V &v) {
254 SparseLinExpr<V> tmp(e);
261 ///\relates SparseLinExpr
264 SparseLinExpr<V> operator+(const V &v,const typename V::ExprValue &c) {
265 SparseLinExpr<V> tmp(v);
272 ///\relates SparseLinExpr
275 SparseLinExpr<V> operator-(const V &v,const typename V::ExprValue &c) {
276 SparseLinExpr<V> tmp(v);
283 ///\relates SparseLinExpr
286 SparseLinExpr<V> operator+(const typename V::ExprValue &c,const V &v) {
287 SparseLinExpr<V> tmp(v);
294 ///\relates SparseLinExpr
297 SparseLinExpr<V> operator-(const typename V::ExprValue &c,const V &v) {
298 SparseLinExpr<V> tmp(c);
305 ///\relates SparseLinExpr
308 SparseLinExpr<V> operator+(const V &v1,const V &v2) {
309 SparseLinExpr<V> tmp(v1);
316 ///\relates SparseLinExpr
319 SparseLinExpr<V> operator*(const V &v,const typename V::ExprValue &c) {
320 SparseLinExpr<V> tmp;
327 ///\relates SparseLinExpr
330 SparseLinExpr<V> operator*(const typename V::ExprValue &c,const V &v) {
331 SparseLinExpr<V> tmp;
338 ///\relates SparseLinExpr
341 SparseLinExpr<V> operator/(const V &v,const typename V::ExprValue &c) {
342 SparseLinExpr<V> tmp;
348 //////////////////////////////////////////////////////////////////////
350 //////////////////////////////////////////////////////////////////////
357 typedef typename E::Var Var;
358 typedef typename E::Coeff Coeff;
360 static const Coeff INF;
361 static const Coeff NaN;
362 // static const Coeff INF=0;
363 // static const Coeff NaN=1;
368 LinConstr() : expr(), lb(NaN), ub(NaN) {}
369 LinConstr(Coeff _lb,const Expr &e,Coeff _ub) :
370 expr(e), lb(_lb), ub(_ub) {}
371 LinConstr(const Expr &e,Coeff _ub) :
372 expr(e), lb(NaN), ub(_ub) {}
373 LinConstr(Coeff _lb,const Expr &e) :
374 expr(e), lb(_lb), ub(NaN) {}
378 const typename LinConstr<E>::Coeff LinConstr<E>::INF=
379 std::numeric_limits<Coeff>::infinity();
381 const typename LinConstr<E>::Coeff LinConstr<E>::NaN=
382 std::numeric_limits<Coeff>::quiet_NaN();
386 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
387 operator<=(const E &e,const E &f)
389 return LinConstr<E>(-LinConstr<E>::INF,e-f,0);
393 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
394 operator>=(const E &e,const E &f)
396 return LinConstr<E>(-LinConstr<E>::INF,f-e,0);
400 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
401 operator==(const E &e,const E &f)
403 return LinConstr<E>(0,e-f,0);
406 //////////////////////////////
409 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
410 operator<=(const E &e,const typename E::Coeff &n)
412 return LinConstr<E>(e,n);
416 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
417 operator>=(const E &e,const typename E::Coeff &n)
419 return LinConstr<E>(n,e);
423 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
424 operator==(const E &e,const typename E::Coeff &n)
426 return LinConstr<E>(n,e,n);
429 //////////////////////////////
432 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
433 operator<=(const typename E::Coeff &n,const E &e)
435 return LinConstr<E>(n,e);
439 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
440 operator>=(const typename E::Coeff &n,const E &e)
442 return LinConstr<E>(e,n);
446 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
447 operator==(const typename E::Coeff &n,const E &e)
449 return LinConstr<E>(n,e,n);
452 //////////////////////////////
455 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
456 operator<=(const typename E::Coeff &n,const LinConstr<E> &c)
459 if(tmp.lb!=tmp.NaN) throw LogicError();
465 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
466 operator>=(const typename E::Coeff &n,const LinConstr<E> &c)
469 if(tmp.ub!=tmp.NaN) throw LogicError();
475 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
476 operator<=(const LinConstr<E> &c,const typename E::Coeff &n)
479 if(tmp.ub!=tmp.NaN) throw LogicError();
485 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
486 operator>=(const LinConstr<E> &c,const typename E::Coeff &n)
489 if(tmp.lb!=tmp.NaN) throw LogicError();
498 #endif //LEMON_LIN_EXPR_H