[Lemon-commits] Peter Kovacs: Support infinite bounds in Circula...
Lemon HG
hg at lemon.cs.elte.hu
Sat Apr 25 18:54:00 CEST 2009
details: http://lemon.cs.elte.hu/hg/lemon/rev/28f58740b6f8
changeset: 654:28f58740b6f8
user: Peter Kovacs <kpeter [at] inf.elte.hu>
date: Sat Apr 25 18:25:59 2009 +0200
description:
Support infinite bounds in Circulation + fixes (#270, #266)
- Support infinite capacities.
- Bug fix in upperMap().
- Fixes and improvements in the documentation.
diffstat:
lemon/circulation.h | 40 ++++++++++++++++++++++++++++++++--------
1 files changed, 32 insertions(+), 8 deletions(-)
diffs (121 lines):
diff --git a/lemon/circulation.h b/lemon/circulation.h
--- a/lemon/circulation.h
+++ b/lemon/circulation.h
@@ -21,6 +21,7 @@
#include <lemon/tolerance.h>
#include <lemon/elevator.h>
+#include <limits>
///\ingroup max_flow
///\file
@@ -119,15 +120,15 @@
at the nodes.
The exact formulation of this problem is the following.
- Let \f$G=(V,A)\f$ be a digraph,
- \f$lower, upper: A\rightarrow\mathbf{R}^+_0\f$ denote the lower and
- upper bounds on the arcs, for which \f$0 \leq lower(uv) \leq upper(uv)\f$
+ Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
+ \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
+ upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
denotes the signed supply values of the nodes.
If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
\f$-sup(u)\f$ demand.
- A feasible circulation is an \f$f: A\rightarrow\mathbf{R}^+_0\f$
+ A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
solution of the following problem.
\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
@@ -151,6 +152,10 @@
the direction of the arcs and taking the negative of the supply values
(e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
+ This algorithm either calculates a feasible circulation, or provides
+ a \ref barrier() "barrier", which prooves that a feasible soultion
+ cannot exist.
+
Note that this algorithm also provides a feasible solution for the
\ref min_cost_flow "minimum cost flow problem".
@@ -337,6 +342,13 @@
private:
+ bool checkBoundMaps() {
+ for (ArcIt e(_g);e!=INVALID;++e) {
+ if (_tol.less((*_up)[e], (*_lo)[e])) return false;
+ }
+ return true;
+ }
+
void createStructures() {
_node_num = _el = countNodes(_g);
@@ -380,7 +392,7 @@
/// Sets the upper bound (capacity) map.
/// \return <tt>(*this)</tt>
- Circulation& upperMap(const LowerMap& map) {
+ Circulation& upperMap(const UpperMap& map) {
_up = ↦
return *this;
}
@@ -467,6 +479,9 @@
/// to the lower bound.
void init()
{
+ LEMON_DEBUG(checkBoundMaps(),
+ "Upper bounds must be greater or equal to the lower bounds");
+
createStructures();
for(NodeIt n(_g);n!=INVALID;++n) {
@@ -496,6 +511,9 @@
/// to construct the initial solution.
void greedyInit()
{
+ LEMON_DEBUG(checkBoundMaps(),
+ "Upper bounds must be greater or equal to the lower bounds");
+
createStructures();
for(NodeIt n(_g);n!=INVALID;++n) {
@@ -503,11 +521,11 @@
}
for (ArcIt e(_g);e!=INVALID;++e) {
- if (!_tol.positive((*_excess)[_g.target(e)] + (*_up)[e])) {
+ if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
_flow->set(e, (*_up)[e]);
(*_excess)[_g.target(e)] += (*_up)[e];
(*_excess)[_g.source(e)] -= (*_up)[e];
- } else if (_tol.positive((*_excess)[_g.target(e)] + (*_lo)[e])) {
+ } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
_flow->set(e, (*_lo)[e]);
(*_excess)[_g.target(e)] += (*_lo)[e];
(*_excess)[_g.source(e)] -= (*_lo)[e];
@@ -748,6 +766,9 @@
bool checkBarrier() const
{
Flow delta=0;
+ Flow inf_cap = std::numeric_limits<Flow>::has_infinity ?
+ std::numeric_limits<Flow>::infinity() :
+ std::numeric_limits<Flow>::max();
for(NodeIt n(_g);n!=INVALID;++n)
if(barrier(n))
delta-=(*_supply)[n];
@@ -755,7 +776,10 @@
{
Node s=_g.source(e);
Node t=_g.target(e);
- if(barrier(s)&&!barrier(t)) delta+=(*_up)[e];
+ if(barrier(s)&&!barrier(t)) {
+ if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
+ delta+=(*_up)[e];
+ }
else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
}
return _tol.negative(delta);
More information about the Lemon-commits
mailing list