260 ///\e |
259 ///\e |
261 |
260 |
262 ///\relates SparseLinExpr |
261 ///\relates SparseLinExpr |
263 /// |
262 /// |
264 template <class V> |
263 template <class V> |
|
264 SparseLinExpr<V> operator+(const V &v,const typename V::ExprValue &c) { |
|
265 SparseLinExpr<V> tmp(v); |
|
266 tmp.constComp()=c; |
|
267 return tmp; |
|
268 } |
|
269 |
|
270 ///\e |
|
271 |
|
272 ///\relates SparseLinExpr |
|
273 /// |
|
274 template <class V> |
|
275 SparseLinExpr<V> operator-(const V &v,const typename V::ExprValue &c) { |
|
276 SparseLinExpr<V> tmp(v); |
|
277 tmp.constComp()=-c; |
|
278 return tmp; |
|
279 } |
|
280 |
|
281 ///\e |
|
282 |
|
283 ///\relates SparseLinExpr |
|
284 /// |
|
285 template <class V> |
|
286 SparseLinExpr<V> operator+(const typename V::ExprValue &c,const V &v) { |
|
287 SparseLinExpr<V> tmp(v); |
|
288 tmp.constComp()=c; |
|
289 return tmp; |
|
290 } |
|
291 |
|
292 ///\e |
|
293 |
|
294 ///\relates SparseLinExpr |
|
295 /// |
|
296 template <class V> |
|
297 SparseLinExpr<V> operator-(const typename V::ExprValue &c,const V &v) { |
|
298 SparseLinExpr<V> tmp(c); |
|
299 tmp[v]=-1; |
|
300 return tmp; |
|
301 } |
|
302 |
|
303 ///\e |
|
304 |
|
305 ///\relates SparseLinExpr |
|
306 /// |
|
307 template <class V> |
265 SparseLinExpr<V> operator+(const V &v1,const V &v2) { |
308 SparseLinExpr<V> operator+(const V &v1,const V &v2) { |
266 SparseLinExpr<V> tmp(v1); |
309 SparseLinExpr<V> tmp(v1); |
267 tmp[v2]+=1; |
310 tmp[v2]+=1; |
268 return tmp; |
311 return tmp; |
269 } |
312 } |
300 tmp[v]=1/c; |
343 tmp[v]=1/c; |
301 return tmp; |
344 return tmp; |
302 } |
345 } |
303 |
346 |
304 |
347 |
|
348 ////////////////////////////////////////////////////////////////////// |
|
349 /// Constraints |
|
350 ////////////////////////////////////////////////////////////////////// |
|
351 |
|
352 template <class E> |
|
353 class LinConstr |
|
354 { |
|
355 public: |
|
356 typedef E Expr; |
|
357 typedef typename E::Var Var; |
|
358 typedef typename E::Coeff Coeff; |
|
359 |
|
360 static const Coeff INF; |
|
361 static const Coeff NaN; |
|
362 // static const Coeff INF=0; |
|
363 // static const Coeff NaN=1; |
|
364 |
|
365 Expr expr; |
|
366 Coeff lb,ub; |
|
367 |
|
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) {} |
|
375 }; |
|
376 |
|
377 template<class E> |
|
378 const typename LinConstr<E>::Coeff LinConstr<E>::INF= |
|
379 std::numeric_limits<Coeff>::infinity(); |
|
380 template<class E> |
|
381 const typename LinConstr<E>::Coeff LinConstr<E>::NaN= |
|
382 std::numeric_limits<Coeff>::quiet_NaN(); |
|
383 |
|
384 |
|
385 template<class E> |
|
386 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
387 operator<=(const E &e,const E &f) |
|
388 { |
|
389 return LinConstr<E>(-LinConstr<E>::INF,e-f,0); |
|
390 } |
|
391 |
|
392 template<class E> |
|
393 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
394 operator>=(const E &e,const E &f) |
|
395 { |
|
396 return LinConstr<E>(-LinConstr<E>::INF,f-e,0); |
|
397 } |
|
398 |
|
399 template<class E> |
|
400 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
401 operator==(const E &e,const E &f) |
|
402 { |
|
403 return LinConstr<E>(0,e-f,0); |
|
404 } |
|
405 |
|
406 ////////////////////////////// |
|
407 |
|
408 template<class E> |
|
409 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
410 operator<=(const E &e,const typename E::Coeff &n) |
|
411 { |
|
412 return LinConstr<E>(e,n); |
|
413 } |
|
414 |
|
415 template<class E> |
|
416 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
417 operator>=(const E &e,const typename E::Coeff &n) |
|
418 { |
|
419 return LinConstr<E>(n,e); |
|
420 } |
|
421 |
|
422 template<class E> |
|
423 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
424 operator==(const E &e,const typename E::Coeff &n) |
|
425 { |
|
426 return LinConstr<E>(n,e,n); |
|
427 } |
|
428 |
|
429 ////////////////////////////// |
|
430 |
|
431 template<class E> |
|
432 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
433 operator<=(const typename E::Coeff &n,const E &e) |
|
434 { |
|
435 return LinConstr<E>(n,e); |
|
436 } |
|
437 |
|
438 template<class E> |
|
439 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
440 operator>=(const typename E::Coeff &n,const E &e) |
|
441 { |
|
442 return LinConstr<E>(e,n); |
|
443 } |
|
444 |
|
445 template<class E> |
|
446 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
447 operator==(const typename E::Coeff &n,const E &e) |
|
448 { |
|
449 return LinConstr<E>(n,e,n); |
|
450 } |
|
451 |
|
452 ////////////////////////////// |
|
453 |
|
454 template<class E> |
|
455 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
456 operator<=(const typename E::Coeff &n,const LinConstr<E> &c) |
|
457 { |
|
458 LinConstr<E> tmp(c); |
|
459 if(tmp.lb!=tmp.NaN) throw LogicError(); |
|
460 else tmp.lb=n; |
|
461 return tmp; |
|
462 } |
|
463 |
|
464 template<class E> |
|
465 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
466 operator>=(const typename E::Coeff &n,const LinConstr<E> &c) |
|
467 { |
|
468 LinConstr<E> tmp(c); |
|
469 if(tmp.ub!=tmp.NaN) throw LogicError(); |
|
470 else tmp.ub=n; |
|
471 return tmp; |
|
472 } |
|
473 |
|
474 template<class E> |
|
475 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
476 operator<=(const LinConstr<E> &c,const typename E::Coeff &n) |
|
477 { |
|
478 LinConstr<E> tmp(c); |
|
479 if(tmp.ub!=tmp.NaN) throw LogicError(); |
|
480 else tmp.ub=n; |
|
481 return tmp; |
|
482 } |
|
483 |
|
484 template<class E> |
|
485 typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type |
|
486 operator>=(const LinConstr<E> &c,const typename E::Coeff &n) |
|
487 { |
|
488 LinConstr<E> tmp(c); |
|
489 if(tmp.lb!=tmp.NaN) throw LogicError(); |
|
490 else tmp.lb=n; |
|
491 return tmp; |
|
492 } |
|
493 |
|
494 |
|
495 |
305 } //namespace lemon |
496 } //namespace lemon |
306 |
497 |
307 #endif //LEMON_LIN_EXPR_H |
498 #endif //LEMON_LIN_EXPR_H |