# HG changeset patch
# User Peter Kovacs <kpeter@inf.elte.hu>
# Date 1240676759 -7200
# Node ID 28f58740b6f8f168a125b9af4c4cf141400645d2
# Parent b95898314e095d3b9f994b1a1068518f25016745
Support infinite bounds in Circulation + fixes (#270, #266)
- Support infinite capacities.
- Bug fix in upperMap().
- Fixes and improvements in the documentation.
diff --git a/lemon/circulation.h b/lemon/circulation.h
a
|
b
|
|
21 | 21 | |
22 | 22 | #include <lemon/tolerance.h> |
23 | 23 | #include <lemon/elevator.h> |
| 24 | #include <limits> |
24 | 25 | |
25 | 26 | ///\ingroup max_flow |
26 | 27 | ///\file |
… |
… |
|
119 | 120 | at the nodes. |
120 | 121 | |
121 | 122 | The exact formulation of this problem is the following. |
122 | | Let \f$G=(V,A)\f$ be a digraph, |
123 | | \f$lower, upper: A\rightarrow\mathbf{R}^+_0\f$ denote the lower and |
124 | | upper bounds on the arcs, for which \f$0 \leq lower(uv) \leq upper(uv)\f$ |
| 123 | Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$ |
| 124 | \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and |
| 125 | upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$ |
125 | 126 | holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$ |
126 | 127 | denotes the signed supply values of the nodes. |
127 | 128 | If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$ |
128 | 129 | supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with |
129 | 130 | \f$-sup(u)\f$ demand. |
130 | | A feasible circulation is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ |
| 131 | A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$ |
131 | 132 | solution of the following problem. |
132 | 133 | |
133 | 134 | \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) |
… |
… |
|
151 | 152 | the direction of the arcs and taking the negative of the supply values |
152 | 153 | (e.g. using \ref ReverseDigraph and \ref NegMap adaptors). |
153 | 154 | |
| 155 | This algorithm either calculates a feasible circulation, or provides |
| 156 | a \ref barrier() "barrier", which prooves that a feasible soultion |
| 157 | cannot exist. |
| 158 | |
154 | 159 | Note that this algorithm also provides a feasible solution for the |
155 | 160 | \ref min_cost_flow "minimum cost flow problem". |
156 | 161 | |
… |
… |
|
337 | 342 | |
338 | 343 | private: |
339 | 344 | |
| 345 | bool checkBoundMaps() { |
| 346 | for (ArcIt e(_g);e!=INVALID;++e) { |
| 347 | if (_tol.less((*_up)[e], (*_lo)[e])) return false; |
| 348 | } |
| 349 | return true; |
| 350 | } |
| 351 | |
340 | 352 | void createStructures() { |
341 | 353 | _node_num = _el = countNodes(_g); |
342 | 354 | |
… |
… |
|
380 | 392 | |
381 | 393 | /// Sets the upper bound (capacity) map. |
382 | 394 | /// \return <tt>(*this)</tt> |
383 | | Circulation& upperMap(const LowerMap& map) { |
| 395 | Circulation& upperMap(const UpperMap& map) { |
384 | 396 | _up = ↦ |
385 | 397 | return *this; |
386 | 398 | } |
… |
… |
|
467 | 479 | /// to the lower bound. |
468 | 480 | void init() |
469 | 481 | { |
| 482 | LEMON_DEBUG(checkBoundMaps(), |
| 483 | "Upper bounds must be greater or equal to the lower bounds"); |
| 484 | |
470 | 485 | createStructures(); |
471 | 486 | |
472 | 487 | for(NodeIt n(_g);n!=INVALID;++n) { |
… |
… |
|
496 | 511 | /// to construct the initial solution. |
497 | 512 | void greedyInit() |
498 | 513 | { |
| 514 | LEMON_DEBUG(checkBoundMaps(), |
| 515 | "Upper bounds must be greater or equal to the lower bounds"); |
| 516 | |
499 | 517 | createStructures(); |
500 | 518 | |
501 | 519 | for(NodeIt n(_g);n!=INVALID;++n) { |
… |
… |
|
503 | 521 | } |
504 | 522 | |
505 | 523 | for (ArcIt e(_g);e!=INVALID;++e) { |
506 | | if (!_tol.positive((*_excess)[_g.target(e)] + (*_up)[e])) { |
| 524 | if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) { |
507 | 525 | _flow->set(e, (*_up)[e]); |
508 | 526 | (*_excess)[_g.target(e)] += (*_up)[e]; |
509 | 527 | (*_excess)[_g.source(e)] -= (*_up)[e]; |
510 | | } else if (_tol.positive((*_excess)[_g.target(e)] + (*_lo)[e])) { |
| 528 | } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) { |
511 | 529 | _flow->set(e, (*_lo)[e]); |
512 | 530 | (*_excess)[_g.target(e)] += (*_lo)[e]; |
513 | 531 | (*_excess)[_g.source(e)] -= (*_lo)[e]; |
… |
… |
|
748 | 766 | bool checkBarrier() const |
749 | 767 | { |
750 | 768 | Flow delta=0; |
| 769 | Flow inf_cap = std::numeric_limits<Flow>::has_infinity ? |
| 770 | std::numeric_limits<Flow>::infinity() : |
| 771 | std::numeric_limits<Flow>::max(); |
751 | 772 | for(NodeIt n(_g);n!=INVALID;++n) |
752 | 773 | if(barrier(n)) |
753 | 774 | delta-=(*_supply)[n]; |
… |
… |
|
755 | 776 | { |
756 | 777 | Node s=_g.source(e); |
757 | 778 | Node t=_g.target(e); |
758 | | if(barrier(s)&&!barrier(t)) delta+=(*_up)[e]; |
| 779 | if(barrier(s)&&!barrier(t)) { |
| 780 | if (_tol.less(inf_cap - (*_up)[e], delta)) return false; |
| 781 | delta+=(*_up)[e]; |
| 782 | } |
759 | 783 | else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e]; |
760 | 784 | } |
761 | 785 | return _tol.negative(delta); |