[Lemon-commits] [lemon_svn] marci: r642 - hugo/trunk/src/work/jacint
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:40:44 CET 2006
Author: marci
Date: Thu Apr 29 19:34:42 2004
New Revision: 642
Modified:
hugo/trunk/src/work/jacint/max_flow.h
Log:
Some docu in MaxFlow class, jacint/max_flow.h
Modified: hugo/trunk/src/work/jacint/max_flow.h
==============================================================================
--- hugo/trunk/src/work/jacint/max_flow.h (original)
+++ hugo/trunk/src/work/jacint/max_flow.h Thu Apr 29 19:34:42 2004
@@ -1,35 +1,35 @@
// -*- C++ -*-
/*
-Heuristics:
- 2 phase
- gap
- list 'level_list' on the nodes on level i implemented by hand
- stack 'active' on the active nodes on level i
- runs heuristic 'highest label' for H1*n relabels
- runs heuristic 'bound decrease' for H0*n relabels, starts with 'highest label'
+ Heuristics:
+ 2 phase
+ gap
+ list 'level_list' on the nodes on level i implemented by hand
+ stack 'active' on the active nodes on level i
+ runs heuristic 'highest label' for H1*n relabels
+ runs heuristic 'bound decrease' for H0*n relabels, starts with 'highest label'
-Parameters H0 and H1 are initialized to 20 and 1.
+ Parameters H0 and H1 are initialized to 20 and 1.
-Constructors:
+ Constructors:
-Preflow(Graph, Node, Node, CapMap, FlowMap, bool) : bool must be false if
- FlowMap is not constant zero, and should be true if it is
+ Preflow(Graph, Node, Node, CapMap, FlowMap, bool) : bool must be false if
+ FlowMap is not constant zero, and should be true if it is
-Members:
+ Members:
-void run()
+ void run()
-Num flowValue() : returns the value of a maximum flow
+ Num flowValue() : returns the value of a maximum flow
-void minMinCut(CutMap& M) : sets M to the characteristic vector of the
- minimum min cut. M should be a map of bools initialized to false. ??Is it OK?
+ void minMinCut(CutMap& M) : sets M to the characteristic vector of the
+ minimum min cut. M should be a map of bools initialized to false. ??Is it OK?
-void maxMinCut(CutMap& M) : sets M to the characteristic vector of the
- maximum min cut. M should be a map of bools initialized to false.
+ void maxMinCut(CutMap& M) : sets M to the characteristic vector of the
+ maximum min cut. M should be a map of bools initialized to false.
-void minCut(CutMap& M) : sets M to the characteristic vector of
- a min cut. M should be a map of bools initialized to false.
+ void minCut(CutMap& M) : sets M to the characteristic vector of
+ a min cut. M should be a map of bools initialized to false.
*/
@@ -52,6 +52,7 @@
namespace hugo {
+ ///\author Marton Makai, Jacint Szabo
template <typename Graph, typename Num,
typename CapMap=typename Graph::template EdgeMap<Num>,
typename FlowMap=typename Graph::template EdgeMap<Num> >
@@ -97,23 +98,39 @@
g(&_G), s(_s), t(_t), capacity(&_capacity),
flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0) {}
+ /// A max flow algorithm is run.
+ ///\pre the flow have to be 0 at the beginning.
void run() {
preflow( ZERO_FLOW );
}
+ /// A preflow algorithm is run. The initial edge-set have to be a flow,
+ /// or from a preflow, according to \c fe.
void preflow( flowEnum fe ) {
preflowPhase0(fe);
preflowPhase1();
}
+ /// Run the first phase of preflow, starting from a 0 flow, from a flow,
+ /// or from a preflow, according to \c fe.
void preflowPhase0( flowEnum fe );
+ /// Second phase of preflow.
void preflowPhase1();
+ /// Starting from a flow, this method searches for an augmenting path
+ /// according to the Edmonds-Karp algorithm
+ /// and augments the flow on if any.
bool augmentOnShortestPath();
+ /// Starting from a flow, this method searches for an augmenting blockin
+ /// flow according to Dinits' algorithm and augments the flow on if any.
+ /// The blocking flow is computed in a physically constructed
+ /// residual graph of type \c Mutablegraph.
template<typename MutableGraph> bool augmentOnBlockingFlow();
+ /// The same as \c augmentOnBlockingFlow<MutableGraph> but the
+ /// residual graph is not constructed physically.
bool augmentOnBlockingFlow2();
/// Returns the actual flow value.
@@ -126,23 +143,26 @@
return a;
}
- //should be used only between preflowPhase0 and preflowPhase1
+ /// Should be used between preflowPhase0 and preflowPhase1.
+ ///\todo We have to make some status variable which shows the actual state
+ /// of the class. This enables us to determine which methods are valid
+ /// for MinCut computation
template<typename _CutMap>
void actMinCut(_CutMap& M) {
NodeIt v;
- for(g->first(v); g->valid(v); g->next(v))
- if ( level[v] < n ) {
- M.set(v,false);
- } else {
- M.set(v,true);
+ for(g->first(v); g->valid(v); g->next(v)) {
+ if ( level[v] < n ) {
+ M.set(v,false);
+ } else {
+ M.set(v,true);
+ }
}
}
-
- /*
- Returns the minimum min cut, by a bfs from s in the residual graph.
- */
+ /// The unique inclusionwise minimum cut is computed by
+ /// processing a bfs from s in the residual graph.
+ ///\pre flow have to be a max flow otherwise it will the whole node-set.
template<typename _CutMap>
void minMinCut(_CutMap& M) {
@@ -176,12 +196,9 @@
}
-
- /*
- Returns the maximum min cut, by a reverse bfs
- from t in the residual graph.
- */
-
+ /// The unique inclusionwise maximum cut is computed by
+ /// processing a reverse bfs from t in the residual graph.
+ ///\pre flow have to be a max flow otherwise it will be empty.
template<typename _CutMap>
void maxMinCut(_CutMap& M) {
@@ -221,21 +238,20 @@
}
+ /// A minimum cut is computed.
template<typename CutMap>
- void minCut(CutMap& M) {
- minMinCut(M);
- }
+ void minCut(CutMap& M) { minMinCut(M); }
- void resetTarget(Node _t) {t=_t;}
+ ///
void resetSource(Node _s) {s=_s;}
+ ///
+ void resetTarget(Node _t) {t=_t;}
- void resetCap(const CapMap& _cap) {
- capacity=&_cap;
- }
+ /// capacity-map is changed.
+ void resetCap(const CapMap& _cap) { capacity=&_cap; }
- void resetFlow(FlowMap& _flow) {
- flow=&_flow;
- }
+ /// flow-map is changed.
+ void resetFlow(FlowMap& _flow) { flow=&_flow; }
private:
@@ -314,130 +330,130 @@
excess.set(w, exc);
return newlevel;
- }
+ }
void preflowPreproc ( flowEnum fe, VecStack& active,
VecNode& level_list, NNMap& left, NNMap& right ) {
- std::queue<Node> bfs_queue;
+ std::queue<Node> bfs_queue;
- switch ( fe ) {
- case ZERO_FLOW:
- {
- //Reverse_bfs from t, to find the starting level.
- level.set(t,0);
- bfs_queue.push(t);
-
- while (!bfs_queue.empty()) {
-
- Node v=bfs_queue.front();
- bfs_queue.pop();
- int l=level[v]+1;
-
- InEdgeIt e;
- for(g->first(e,v); g->valid(e); g->next(e)) {
- Node w=g->tail(e);
- if ( level[w] == n && w != s ) {
- bfs_queue.push(w);
- Node first=level_list[l];
- if ( g->valid(first) ) left.set(first,w);
- right.set(w,first);
- level_list[l]=w;
- level.set(w, l);
- }
- }
- }
+ switch ( fe ) {
+ case ZERO_FLOW:
+ {
+ //Reverse_bfs from t, to find the starting level.
+ level.set(t,0);
+ bfs_queue.push(t);
+
+ while (!bfs_queue.empty()) {
+
+ Node v=bfs_queue.front();
+ bfs_queue.pop();
+ int l=level[v]+1;
+
+ InEdgeIt e;
+ for(g->first(e,v); g->valid(e); g->next(e)) {
+ Node w=g->tail(e);
+ if ( level[w] == n && w != s ) {
+ bfs_queue.push(w);
+ Node first=level_list[l];
+ if ( g->valid(first) ) left.set(first,w);
+ right.set(w,first);
+ level_list[l]=w;
+ level.set(w, l);
+ }
+ }
+ }
- //the starting flow
- OutEdgeIt e;
- for(g->first(e,s); g->valid(e); g->next(e))
- {
- Num c=(*capacity)[e];
- if ( c <= 0 ) continue;
- Node w=g->head(e);
- if ( level[w] < n ) {
- if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
- flow->set(e, c);
- excess.set(w, excess[w]+c);
- }
- }
- break;
- }
+ //the starting flow
+ OutEdgeIt e;
+ for(g->first(e,s); g->valid(e); g->next(e))
+ {
+ Num c=(*capacity)[e];
+ if ( c <= 0 ) continue;
+ Node w=g->head(e);
+ if ( level[w] < n ) {
+ if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
+ flow->set(e, c);
+ excess.set(w, excess[w]+c);
+ }
+ }
+ break;
+ }
- case GEN_FLOW:
- case PREFLOW:
- {
- //Reverse_bfs from t in the residual graph,
- //to find the starting level.
- level.set(t,0);
- bfs_queue.push(t);
-
- while (!bfs_queue.empty()) {
-
- Node v=bfs_queue.front();
- bfs_queue.pop();
- int l=level[v]+1;
-
- InEdgeIt e;
- for(g->first(e,v); g->valid(e); g->next(e)) {
- if ( (*capacity)[e] <= (*flow)[e] ) continue;
- Node w=g->tail(e);
- if ( level[w] == n && w != s ) {
- bfs_queue.push(w);
- Node first=level_list[l];
- if ( g->valid(first) ) left.set(first,w);
- right.set(w,first);
- level_list[l]=w;
- level.set(w, l);
- }
- }
+ case GEN_FLOW:
+ case PREFLOW:
+ {
+ //Reverse_bfs from t in the residual graph,
+ //to find the starting level.
+ level.set(t,0);
+ bfs_queue.push(t);
+
+ while (!bfs_queue.empty()) {
- OutEdgeIt f;
- for(g->first(f,v); g->valid(f); g->next(f)) {
- if ( 0 >= (*flow)[f] ) continue;
- Node w=g->head(f);
- if ( level[w] == n && w != s ) {
- bfs_queue.push(w);
- Node first=level_list[l];
- if ( g->valid(first) ) left.set(first,w);
- right.set(w,first);
- level_list[l]=w;
- level.set(w, l);
- }
- }
- }
+ Node v=bfs_queue.front();
+ bfs_queue.pop();
+ int l=level[v]+1;
+
+ InEdgeIt e;
+ for(g->first(e,v); g->valid(e); g->next(e)) {
+ if ( (*capacity)[e] <= (*flow)[e] ) continue;
+ Node w=g->tail(e);
+ if ( level[w] == n && w != s ) {
+ bfs_queue.push(w);
+ Node first=level_list[l];
+ if ( g->valid(first) ) left.set(first,w);
+ right.set(w,first);
+ level_list[l]=w;
+ level.set(w, l);
+ }
+ }
+
+ OutEdgeIt f;
+ for(g->first(f,v); g->valid(f); g->next(f)) {
+ if ( 0 >= (*flow)[f] ) continue;
+ Node w=g->head(f);
+ if ( level[w] == n && w != s ) {
+ bfs_queue.push(w);
+ Node first=level_list[l];
+ if ( g->valid(first) ) left.set(first,w);
+ right.set(w,first);
+ level_list[l]=w;
+ level.set(w, l);
+ }
+ }
+ }
- //the starting flow
- OutEdgeIt e;
- for(g->first(e,s); g->valid(e); g->next(e))
- {
- Num rem=(*capacity)[e]-(*flow)[e];
- if ( rem <= 0 ) continue;
- Node w=g->head(e);
- if ( level[w] < n ) {
- if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
- flow->set(e, (*capacity)[e]);
- excess.set(w, excess[w]+rem);
- }
- }
+ //the starting flow
+ OutEdgeIt e;
+ for(g->first(e,s); g->valid(e); g->next(e))
+ {
+ Num rem=(*capacity)[e]-(*flow)[e];
+ if ( rem <= 0 ) continue;
+ Node w=g->head(e);
+ if ( level[w] < n ) {
+ if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
+ flow->set(e, (*capacity)[e]);
+ excess.set(w, excess[w]+rem);
+ }
+ }
- InEdgeIt f;
- for(g->first(f,s); g->valid(f); g->next(f))
- {
- if ( (*flow)[f] <= 0 ) continue;
- Node w=g->tail(f);
- if ( level[w] < n ) {
- if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
- excess.set(w, excess[w]+(*flow)[f]);
- flow->set(f, 0);
- }
- }
- break;
- } //case PREFLOW
- }
- } //preflowPreproc
+ InEdgeIt f;
+ for(g->first(f,s); g->valid(f); g->next(f))
+ {
+ if ( (*flow)[f] <= 0 ) continue;
+ Node w=g->tail(f);
+ if ( level[w] < n ) {
+ if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
+ excess.set(w, excess[w]+(*flow)[f]);
+ flow->set(f, 0);
+ }
+ }
+ break;
+ } //case PREFLOW
+ }
+ } //preflowPreproc
@@ -521,11 +537,11 @@
dist.set(n, a);
}
int operator[](const typename MapGraphWrapper::Node& n)
- { return dist[n]; }
-// int get(const typename MapGraphWrapper::Node& n) const {
-// return dist[n]; }
-// bool get(const typename MapGraphWrapper::Edge& e) const {
-// return (dist.get(g->tail(e))<dist.get(g->head(e))); }
+ { return dist[n]; }
+ // int get(const typename MapGraphWrapper::Node& n) const {
+ // return dist[n]; }
+ // bool get(const typename MapGraphWrapper::Edge& e) const {
+ // return (dist.get(g->tail(e))<dist.get(g->head(e))); }
bool operator[](const typename MapGraphWrapper::Edge& e) const {
return (dist[g->tail(e)]<dist[g->head(e)]);
}
@@ -538,108 +554,108 @@
void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase0( flowEnum fe )
{
- int heur0=(int)(H0*n); //time while running 'bound decrease'
- int heur1=(int)(H1*n); //time while running 'highest label'
- int heur=heur1; //starting time interval (#of relabels)
- int numrelabel=0;
+ int heur0=(int)(H0*n); //time while running 'bound decrease'
+ int heur1=(int)(H1*n); //time while running 'highest label'
+ int heur=heur1; //starting time interval (#of relabels)
+ int numrelabel=0;
- bool what_heur=1;
- //It is 0 in case 'bound decrease' and 1 in case 'highest label'
+ bool what_heur=1;
+ //It is 0 in case 'bound decrease' and 1 in case 'highest label'
- bool end=false;
- //Needed for 'bound decrease', true means no active nodes are above bound b.
+ bool end=false;
+ //Needed for 'bound decrease', true means no active nodes are above bound b.
- int k=n-2; //bound on the highest level under n containing a node
- int b=k; //bound on the highest level under n of an active node
+ int k=n-2; //bound on the highest level under n containing a node
+ int b=k; //bound on the highest level under n of an active node
- VecStack active(n);
+ VecStack active(n);
- NNMap left(*g, INVALID);
- NNMap right(*g, INVALID);
- VecNode level_list(n,INVALID);
- //List of the nodes in level i<n, set to n.
+ NNMap left(*g, INVALID);
+ NNMap right(*g, INVALID);
+ VecNode level_list(n,INVALID);
+ //List of the nodes in level i<n, set to n.
- NodeIt v;
- for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
- //setting each node to level n
+ NodeIt v;
+ for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
+ //setting each node to level n
- switch ( fe ) {
- case PREFLOW:
- {
- //counting the excess
- NodeIt v;
- for(g->first(v); g->valid(v); g->next(v)) {
- Num exc=0;
-
- InEdgeIt e;
- for(g->first(e,v); g->valid(e); g->next(e)) exc+=(*flow)[e];
- OutEdgeIt f;
- for(g->first(f,v); g->valid(f); g->next(f)) exc-=(*flow)[f];
-
- excess.set(v,exc);
-
- //putting the active nodes into the stack
- int lev=level[v];
- if ( exc > 0 && lev < n && v != t ) active[lev].push(v);
- }
- break;
- }
- case GEN_FLOW:
- {
- //Counting the excess of t
+ switch ( fe ) {
+ case PREFLOW:
+ {
+ //counting the excess
+ NodeIt v;
+ for(g->first(v); g->valid(v); g->next(v)) {
Num exc=0;
InEdgeIt e;
- for(g->first(e,t); g->valid(e); g->next(e)) exc+=(*flow)[e];
+ for(g->first(e,v); g->valid(e); g->next(e)) exc+=(*flow)[e];
OutEdgeIt f;
- for(g->first(f,t); g->valid(f); g->next(f)) exc-=(*flow)[f];
+ for(g->first(f,v); g->valid(f); g->next(f)) exc-=(*flow)[f];
+
+ excess.set(v,exc);
+
+ //putting the active nodes into the stack
+ int lev=level[v];
+ if ( exc > 0 && lev < n && v != t ) active[lev].push(v);
+ }
+ break;
+ }
+ case GEN_FLOW:
+ {
+ //Counting the excess of t
+ Num exc=0;
- excess.set(t,exc);
+ InEdgeIt e;
+ for(g->first(e,t); g->valid(e); g->next(e)) exc+=(*flow)[e];
+ OutEdgeIt f;
+ for(g->first(f,t); g->valid(f); g->next(f)) exc-=(*flow)[f];
+
+ excess.set(t,exc);
- break;
- }
- default:
break;
}
+ default:
+ break;
+ }
- preflowPreproc( fe, active, level_list, left, right );
- //End of preprocessing
+ preflowPreproc( fe, active, level_list, left, right );
+ //End of preprocessing
- //Push/relabel on the highest level active nodes.
- while ( true ) {
- if ( b == 0 ) {
- if ( !what_heur && !end && k > 0 ) {
- b=k;
- end=true;
- } else break;
- }
+ //Push/relabel on the highest level active nodes.
+ while ( true ) {
+ if ( b == 0 ) {
+ if ( !what_heur && !end && k > 0 ) {
+ b=k;
+ end=true;
+ } else break;
+ }
- if ( active[b].empty() ) --b;
- else {
- end=false;
- Node w=active[b].top();
- active[b].pop();
- int newlevel=push(w,active);
- if ( excess[w] > 0 ) relabel(w, newlevel, active, level_list,
- left, right, b, k, what_heur);
-
- ++numrelabel;
- if ( numrelabel >= heur ) {
- numrelabel=0;
- if ( what_heur ) {
- what_heur=0;
- heur=heur0;
- end=false;
- } else {
- what_heur=1;
- heur=heur1;
- b=k;
- }
+ if ( active[b].empty() ) --b;
+ else {
+ end=false;
+ Node w=active[b].top();
+ active[b].pop();
+ int newlevel=push(w,active);
+ if ( excess[w] > 0 ) relabel(w, newlevel, active, level_list,
+ left, right, b, k, what_heur);
+
+ ++numrelabel;
+ if ( numrelabel >= heur ) {
+ numrelabel=0;
+ if ( what_heur ) {
+ what_heur=0;
+ heur=heur0;
+ end=false;
+ } else {
+ what_heur=1;
+ heur=heur1;
+ b=k;
}
- }
+ }
}
- }
+ }
+ }
@@ -647,113 +663,113 @@
void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase1()
{
- int k=n-2; //bound on the highest level under n containing a node
- int b=k; //bound on the highest level under n of an active node
+ int k=n-2; //bound on the highest level under n containing a node
+ int b=k; //bound on the highest level under n of an active node
- VecStack active(n);
- level.set(s,0);
- std::queue<Node> bfs_queue;
- bfs_queue.push(s);
-
- while (!bfs_queue.empty()) {
-
- Node v=bfs_queue.front();
- bfs_queue.pop();
- int l=level[v]+1;
+ VecStack active(n);
+ level.set(s,0);
+ std::queue<Node> bfs_queue;
+ bfs_queue.push(s);
+
+ while (!bfs_queue.empty()) {
+
+ Node v=bfs_queue.front();
+ bfs_queue.pop();
+ int l=level[v]+1;
- InEdgeIt e;
- for(g->first(e,v); g->valid(e); g->next(e)) {
- if ( (*capacity)[e] <= (*flow)[e] ) continue;
- Node u=g->tail(e);
- if ( level[u] >= n ) {
- bfs_queue.push(u);
- level.set(u, l);
- if ( excess[u] > 0 ) active[l].push(u);
- }
+ InEdgeIt e;
+ for(g->first(e,v); g->valid(e); g->next(e)) {
+ if ( (*capacity)[e] <= (*flow)[e] ) continue;
+ Node u=g->tail(e);
+ if ( level[u] >= n ) {
+ bfs_queue.push(u);
+ level.set(u, l);
+ if ( excess[u] > 0 ) active[l].push(u);
}
+ }
- OutEdgeIt f;
- for(g->first(f,v); g->valid(f); g->next(f)) {
- if ( 0 >= (*flow)[f] ) continue;
- Node u=g->head(f);
- if ( level[u] >= n ) {
- bfs_queue.push(u);
- level.set(u, l);
- if ( excess[u] > 0 ) active[l].push(u);
- }
+ OutEdgeIt f;
+ for(g->first(f,v); g->valid(f); g->next(f)) {
+ if ( 0 >= (*flow)[f] ) continue;
+ Node u=g->head(f);
+ if ( level[u] >= n ) {
+ bfs_queue.push(u);
+ level.set(u, l);
+ if ( excess[u] > 0 ) active[l].push(u);
}
}
- b=n-2;
+ }
+ b=n-2;
- while ( true ) {
+ while ( true ) {
- if ( b == 0 ) break;
+ if ( b == 0 ) break;
- if ( active[b].empty() ) --b;
- else {
- Node w=active[b].top();
- active[b].pop();
- int newlevel=push(w,active);
-
- //relabel
- if ( excess[w] > 0 ) {
- level.set(w,++newlevel);
- active[newlevel].push(w);
- b=newlevel;
- }
- } // if stack[b] is nonempty
- } // while(true)
- }
+ if ( active[b].empty() ) --b;
+ else {
+ Node w=active[b].top();
+ active[b].pop();
+ int newlevel=push(w,active);
+
+ //relabel
+ if ( excess[w] > 0 ) {
+ level.set(w,++newlevel);
+ active[newlevel].push(w);
+ b=newlevel;
+ }
+ } // if stack[b] is nonempty
+ } // while(true)
+ }
template <typename Graph, typename Num, typename CapMap, typename FlowMap>
bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath()
{
- ResGW res_graph(*g, *capacity, *flow);
- bool _augment=false;
+ ResGW res_graph(*g, *capacity, *flow);
+ bool _augment=false;
- //ReachedMap level(res_graph);
- FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
- BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
- bfs.pushAndSetReached(s);
+ //ReachedMap level(res_graph);
+ FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
+ BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
+ bfs.pushAndSetReached(s);
- typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
- pred.set(s, INVALID);
+ typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
+ pred.set(s, INVALID);
- typename ResGW::template NodeMap<Num> free(res_graph);
+ typename ResGW::template NodeMap<Num> free(res_graph);
- //searching for augmenting path
- while ( !bfs.finished() ) {
- ResGWOutEdgeIt e=bfs;
- if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
- Node v=res_graph.tail(e);
- Node w=res_graph.head(e);
- pred.set(w, e);
- if (res_graph.valid(pred[v])) {
- free.set(w, std::min(free[v], res_graph.resCap(e)));
- } else {
- free.set(w, res_graph.resCap(e));
- }
- if (res_graph.head(e)==t) { _augment=true; break; }
+ //searching for augmenting path
+ while ( !bfs.finished() ) {
+ ResGWOutEdgeIt e=bfs;
+ if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+ Node v=res_graph.tail(e);
+ Node w=res_graph.head(e);
+ pred.set(w, e);
+ if (res_graph.valid(pred[v])) {
+ free.set(w, std::min(free[v], res_graph.resCap(e)));
+ } else {
+ free.set(w, res_graph.resCap(e));
}
+ if (res_graph.head(e)==t) { _augment=true; break; }
+ }
- ++bfs;
- } //end of searching augmenting path
+ ++bfs;
+ } //end of searching augmenting path
- if (_augment) {
- Node n=t;
- Num augment_value=free[t];
- while (res_graph.valid(pred[n])) {
- ResGWEdge e=pred[n];
- res_graph.augment(e, augment_value);
- n=res_graph.tail(e);
- }
+ if (_augment) {
+ Node n=t;
+ Num augment_value=free[t];
+ while (res_graph.valid(pred[n])) {
+ ResGWEdge e=pred[n];
+ res_graph.augment(e, augment_value);
+ n=res_graph.tail(e);
}
-
- return _augment;
}
+ return _augment;
+ }
+
@@ -766,114 +782,114 @@
template<typename MutableGraph>
bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow()
{
- typedef MutableGraph MG;
- bool _augment=false;
+ typedef MutableGraph MG;
+ bool _augment=false;
- ResGW res_graph(*g, *capacity, *flow);
+ ResGW res_graph(*g, *capacity, *flow);
- //bfs for distances on the residual graph
- //ReachedMap level(res_graph);
- FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
- BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
- bfs.pushAndSetReached(s);
- typename ResGW::template NodeMap<int>
- dist(res_graph); //filled up with 0's
-
- //F will contain the physical copy of the residual graph
- //with the set of edges which are on shortest paths
- MG F;
- typename ResGW::template NodeMap<typename MG::Node>
- res_graph_to_F(res_graph);
- {
- typename ResGW::NodeIt n;
- for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
- res_graph_to_F.set(n, F.addNode());
- }
+ //bfs for distances on the residual graph
+ //ReachedMap level(res_graph);
+ FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
+ BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
+ bfs.pushAndSetReached(s);
+ typename ResGW::template NodeMap<int>
+ dist(res_graph); //filled up with 0's
+
+ //F will contain the physical copy of the residual graph
+ //with the set of edges which are on shortest paths
+ MG F;
+ typename ResGW::template NodeMap<typename MG::Node>
+ res_graph_to_F(res_graph);
+ {
+ typename ResGW::NodeIt n;
+ for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
+ res_graph_to_F.set(n, F.addNode());
}
+ }
- typename MG::Node sF=res_graph_to_F[s];
- typename MG::Node tF=res_graph_to_F[t];
- typename MG::template EdgeMap<ResGWEdge> original_edge(F);
- typename MG::template EdgeMap<Num> residual_capacity(F);
-
- while ( !bfs.finished() ) {
- ResGWOutEdgeIt e=bfs;
- if (res_graph.valid(e)) {
- if (bfs.isBNodeNewlyReached()) {
- dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
+ typename MG::Node sF=res_graph_to_F[s];
+ typename MG::Node tF=res_graph_to_F[t];
+ typename MG::template EdgeMap<ResGWEdge> original_edge(F);
+ typename MG::template EdgeMap<Num> residual_capacity(F);
+
+ while ( !bfs.finished() ) {
+ ResGWOutEdgeIt e=bfs;
+ if (res_graph.valid(e)) {
+ if (bfs.isBNodeNewlyReached()) {
+ dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
+ typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
+ original_edge.update();
+ original_edge.set(f, e);
+ residual_capacity.update();
+ residual_capacity.set(f, res_graph.resCap(e));
+ } else {
+ if (dist[res_graph.head(e)]==(dist[res_graph.tail(e)]+1)) {
typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
original_edge.update();
original_edge.set(f, e);
residual_capacity.update();
residual_capacity.set(f, res_graph.resCap(e));
- } else {
- if (dist[res_graph.head(e)]==(dist[res_graph.tail(e)]+1)) {
- typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
- original_edge.update();
- original_edge.set(f, e);
- residual_capacity.update();
- residual_capacity.set(f, res_graph.resCap(e));
- }
}
}
- ++bfs;
- } //computing distances from s in the residual graph
+ }
+ ++bfs;
+ } //computing distances from s in the residual graph
- bool __augment=true;
+ bool __augment=true;
- while (__augment) {
- __augment=false;
- //computing blocking flow with dfs
- DfsIterator< MG, typename MG::template NodeMap<bool> > dfs(F);
- typename MG::template NodeMap<typename MG::Edge> pred(F);
- pred.set(sF, INVALID);
- //invalid iterators for sources
-
- typename MG::template NodeMap<Num> free(F);
-
- dfs.pushAndSetReached(sF);
- while (!dfs.finished()) {
- ++dfs;
- if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
- if (dfs.isBNodeNewlyReached()) {
- typename MG::Node v=F.aNode(dfs);
- typename MG::Node w=F.bNode(dfs);
- pred.set(w, dfs);
- if (F.valid(pred[v])) {
- free.set(w, std::min(free[v], residual_capacity[dfs]));
- } else {
- free.set(w, residual_capacity[dfs]);
- }
- if (w==tF) {
- __augment=true;
- _augment=true;
- break;
- }
-
+ while (__augment) {
+ __augment=false;
+ //computing blocking flow with dfs
+ DfsIterator< MG, typename MG::template NodeMap<bool> > dfs(F);
+ typename MG::template NodeMap<typename MG::Edge> pred(F);
+ pred.set(sF, INVALID);
+ //invalid iterators for sources
+
+ typename MG::template NodeMap<Num> free(F);
+
+ dfs.pushAndSetReached(sF);
+ while (!dfs.finished()) {
+ ++dfs;
+ if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
+ if (dfs.isBNodeNewlyReached()) {
+ typename MG::Node v=F.aNode(dfs);
+ typename MG::Node w=F.bNode(dfs);
+ pred.set(w, dfs);
+ if (F.valid(pred[v])) {
+ free.set(w, std::min(free[v], residual_capacity[dfs]));
} else {
- F.erase(/*typename MG::OutEdgeIt*/(dfs));
+ free.set(w, residual_capacity[dfs]);
}
- }
- }
-
- if (__augment) {
- typename MG::Node n=tF;
- Num augment_value=free[tF];
- while (F.valid(pred[n])) {
- typename MG::Edge e=pred[n];
- res_graph.augment(original_edge[e], augment_value);
- n=F.tail(e);
- if (residual_capacity[e]==augment_value)
- F.erase(e);
- else
- residual_capacity.set(e, residual_capacity[e]-augment_value);
+ if (w==tF) {
+ __augment=true;
+ _augment=true;
+ break;
+ }
+
+ } else {
+ F.erase(/*typename MG::OutEdgeIt*/(dfs));
}
+ }
+ }
+
+ if (__augment) {
+ typename MG::Node n=tF;
+ Num augment_value=free[tF];
+ while (F.valid(pred[n])) {
+ typename MG::Edge e=pred[n];
+ res_graph.augment(original_edge[e], augment_value);
+ n=F.tail(e);
+ if (residual_capacity[e]==augment_value)
+ F.erase(e);
+ else
+ residual_capacity.set(e, residual_capacity[e]-augment_value);
}
-
}
-
- return _augment;
+
}
+
+ return _augment;
+ }
@@ -883,75 +899,75 @@
template <typename Graph, typename Num, typename CapMap, typename FlowMap>
bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow2()
{
- bool _augment=false;
+ bool _augment=false;
- ResGW res_graph(*g, *capacity, *flow);
+ ResGW res_graph(*g, *capacity, *flow);
- //ReachedMap level(res_graph);
- FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
- BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
-
- bfs.pushAndSetReached(s);
- DistanceMap<ResGW> dist(res_graph);
- while ( !bfs.finished() ) {
- ResGWOutEdgeIt e=bfs;
- if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
- dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
- }
- ++bfs;
- } //computing distances from s in the residual graph
+ //ReachedMap level(res_graph);
+ FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
+ BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
+
+ bfs.pushAndSetReached(s);
+ DistanceMap<ResGW> dist(res_graph);
+ while ( !bfs.finished() ) {
+ ResGWOutEdgeIt e=bfs;
+ if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+ dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
+ }
+ ++bfs;
+ } //computing distances from s in the residual graph
//Subgraph containing the edges on some shortest paths
- ConstMap<typename ResGW::Node, bool> true_map(true);
- typedef SubGraphWrapper<ResGW, ConstMap<typename ResGW::Node, bool>,
- DistanceMap<ResGW> > FilterResGW;
- FilterResGW filter_res_graph(res_graph, true_map, dist);
-
- //Subgraph, which is able to delete edges which are already
- //met by the dfs
- typename FilterResGW::template NodeMap<typename FilterResGW::OutEdgeIt>
- first_out_edges(filter_res_graph);
- typename FilterResGW::NodeIt v;
- for(filter_res_graph.first(v); filter_res_graph.valid(v);
- filter_res_graph.next(v))
+ ConstMap<typename ResGW::Node, bool> true_map(true);
+ typedef SubGraphWrapper<ResGW, ConstMap<typename ResGW::Node, bool>,
+ DistanceMap<ResGW> > FilterResGW;
+ FilterResGW filter_res_graph(res_graph, true_map, dist);
+
+ //Subgraph, which is able to delete edges which are already
+ //met by the dfs
+ typename FilterResGW::template NodeMap<typename FilterResGW::OutEdgeIt>
+ first_out_edges(filter_res_graph);
+ typename FilterResGW::NodeIt v;
+ for(filter_res_graph.first(v); filter_res_graph.valid(v);
+ filter_res_graph.next(v))
{
typename FilterResGW::OutEdgeIt e;
filter_res_graph.first(e, v);
first_out_edges.set(v, e);
}
- typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
- template NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
- ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
-
- bool __augment=true;
-
- while (__augment) {
-
- __augment=false;
- //computing blocking flow with dfs
- DfsIterator< ErasingResGW,
- typename ErasingResGW::template NodeMap<bool> >
- dfs(erasing_res_graph);
- typename ErasingResGW::
- template NodeMap<typename ErasingResGW::OutEdgeIt>
- pred(erasing_res_graph);
- pred.set(s, INVALID);
- //invalid iterators for sources
-
- typename ErasingResGW::template NodeMap<Num>
- free1(erasing_res_graph);
-
- dfs.pushAndSetReached(
- typename ErasingResGW::Node(
- typename FilterResGW::Node(
- typename ResGW::Node(s)
- )
- )
- );
- while (!dfs.finished()) {
- ++dfs;
- if (erasing_res_graph.valid(
- typename ErasingResGW::OutEdgeIt(dfs)))
+ typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
+ template NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
+ ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
+
+ bool __augment=true;
+
+ while (__augment) {
+
+ __augment=false;
+ //computing blocking flow with dfs
+ DfsIterator< ErasingResGW,
+ typename ErasingResGW::template NodeMap<bool> >
+ dfs(erasing_res_graph);
+ typename ErasingResGW::
+ template NodeMap<typename ErasingResGW::OutEdgeIt>
+ pred(erasing_res_graph);
+ pred.set(s, INVALID);
+ //invalid iterators for sources
+
+ typename ErasingResGW::template NodeMap<Num>
+ free1(erasing_res_graph);
+
+ dfs.pushAndSetReached(
+ typename ErasingResGW::Node(
+ typename FilterResGW::Node(
+ typename ResGW::Node(s)
+ )
+ )
+ );
+ while (!dfs.finished()) {
+ ++dfs;
+ if (erasing_res_graph.valid(
+ typename ErasingResGW::OutEdgeIt(dfs)))
{
if (dfs.isBNodeNewlyReached()) {
@@ -961,10 +977,10 @@
pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs));
if (erasing_res_graph.valid(pred[v])) {
free1.set(w, std::min(free1[v], res_graph.resCap(
- typename ErasingResGW::OutEdgeIt(dfs))));
+ typename ErasingResGW::OutEdgeIt(dfs))));
} else {
free1.set(w, res_graph.resCap(
- typename ErasingResGW::OutEdgeIt(dfs)));
+ typename ErasingResGW::OutEdgeIt(dfs)));
}
if (w==t) {
@@ -976,33 +992,33 @@
erasing_res_graph.erase(dfs);
}
}
- }
+ }
- if (__augment) {
- typename ErasingResGW::Node n=typename FilterResGW::Node(typename ResGW::Node(t));
-// typename ResGW::NodeMap<Num> a(res_graph);
-// typename ResGW::Node b;
-// Num j=a[b];
-// typename FilterResGW::NodeMap<Num> a1(filter_res_graph);
-// typename FilterResGW::Node b1;
-// Num j1=a1[b1];
-// typename ErasingResGW::NodeMap<Num> a2(erasing_res_graph);
-// typename ErasingResGW::Node b2;
-// Num j2=a2[b2];
- Num augment_value=free1[n];
- while (erasing_res_graph.valid(pred[n])) {
- typename ErasingResGW::OutEdgeIt e=pred[n];
- res_graph.augment(e, augment_value);
- n=erasing_res_graph.tail(e);
- if (res_graph.resCap(e)==0)
- erasing_res_graph.erase(e);
+ if (__augment) {
+ typename ErasingResGW::Node n=typename FilterResGW::Node(typename ResGW::Node(t));
+ // typename ResGW::NodeMap<Num> a(res_graph);
+ // typename ResGW::Node b;
+ // Num j=a[b];
+ // typename FilterResGW::NodeMap<Num> a1(filter_res_graph);
+ // typename FilterResGW::Node b1;
+ // Num j1=a1[b1];
+ // typename ErasingResGW::NodeMap<Num> a2(erasing_res_graph);
+ // typename ErasingResGW::Node b2;
+ // Num j2=a2[b2];
+ Num augment_value=free1[n];
+ while (erasing_res_graph.valid(pred[n])) {
+ typename ErasingResGW::OutEdgeIt e=pred[n];
+ res_graph.augment(e, augment_value);
+ n=erasing_res_graph.tail(e);
+ if (res_graph.resCap(e)==0)
+ erasing_res_graph.erase(e);
}
}
- } //while (__augment)
+ } //while (__augment)
- return _augment;
- }
+ return _augment;
+ }
More information about the Lemon-commits
mailing list