[Lemon-commits] [lemon_svn] alpar: r981 - in hugo/trunk/src: hugo work/jacint
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:42:33 CET 2006
Author: alpar
Date: Thu Jul 22 16:19:23 2004
New Revision: 981
Added:
hugo/trunk/src/hugo/max_flow.h
- copied, changed from r973, /hugo/trunk/src/work/jacint/max_flow_no_stack.h
Removed:
hugo/trunk/src/work/jacint/max_flow_no_stack.h
Log:
max_flow.h (wich doesn't use STL
- max_flow.h (which doesn't use STL stack) moved to /src/hugo
- for_each_macros.h was removed from max_flow.h
- (blocking) flow augmenting stuffs was removed.
Copied: hugo/trunk/src/hugo/max_flow.h (from r973, /hugo/trunk/src/work/jacint/max_flow_no_stack.h)
==============================================================================
--- /hugo/trunk/src/work/jacint/max_flow_no_stack.h (original)
+++ hugo/trunk/src/hugo/max_flow.h Thu Jul 22 16:19:23 2004
@@ -7,10 +7,8 @@
//#include <stack>
#include <hugo/graph_wrapper.h>
-#include <bfs_dfs.h>
#include <hugo/invalid.h>
#include <hugo/maps.h>
-#include <hugo/for_each_macros.h>
/// \file
/// \brief The same as max_flow.h, but without using stl stack for the active nodes. Only for test.
@@ -45,7 +43,7 @@
template <typename Graph, typename Num,
typename CapMap=typename Graph::template EdgeMap<Num>,
typename FlowMap=typename Graph::template EdgeMap<Num> >
- class MaxFlowNoStack {
+ class MaxFlow {
protected:
typedef typename Graph::Node Node;
typedef typename Graph::NodeIt NodeIt;
@@ -80,22 +78,6 @@
//excess is needed only in preflow
typename Graph::template NodeMap<Num> excess;
- //fixme
-// protected:
- // MaxFlow() { }
- // void set(const Graph& _G, Node _s, Node _t, const CapMap& _capacity,
- // FlowMap& _flow)
- // {
- // g=&_G;
- // s=_s;
- // t=_t;
- // capacity=&_capacity;
- // flow=&_flow;
- // n=_G.nodeNum;
- // level.set (_G); //kellene vmi ilyesmi fv
- // excess(_G,0); //itt is
- // }
-
// constants used for heuristics
static const int H0=20;
static const int H1=1;
@@ -130,37 +112,38 @@
/// Don not needle this flag only if necessary.
StatusEnum status;
- int number_of_augmentations;
+// int number_of_augmentations;
- template<typename IntMap>
- class TrickyReachedMap {
- protected:
- IntMap* map;
- int* number_of_augmentations;
- public:
- TrickyReachedMap(IntMap& _map, int& _number_of_augmentations) :
- map(&_map), number_of_augmentations(&_number_of_augmentations) { }
- void set(const Node& n, bool b) {
- if (b)
- map->set(n, *number_of_augmentations);
- else
- map->set(n, *number_of_augmentations-1);
- }
- bool operator[](const Node& n) const {
- return (*map)[n]==*number_of_augmentations;
- }
- };
+
+// template<typename IntMap>
+// class TrickyReachedMap {
+// protected:
+// IntMap* map;
+// int* number_of_augmentations;
+// public:
+// TrickyReachedMap(IntMap& _map, int& _number_of_augmentations) :
+// map(&_map), number_of_augmentations(&_number_of_augmentations) { }
+// void set(const Node& n, bool b) {
+// if (b)
+// map->set(n, *number_of_augmentations);
+// else
+// map->set(n, *number_of_augmentations-1);
+// }
+// bool operator[](const Node& n) const {
+// return (*map)[n]==*number_of_augmentations;
+// }
+// };
///Constructor
///\todo Document, please.
///
- MaxFlowNoStack(const Graph& _G, Node _s, Node _t,
+ MaxFlow(const Graph& _G, Node _s, Node _t,
const CapMap& _capacity, FlowMap& _flow) :
g(&_G), s(_s), t(_t), capacity(&_capacity),
flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0),
- status(AFTER_NOTHING), number_of_augmentations(0) { }
+ status(AFTER_NOTHING) { }
///Runs a maximum flow algorithm.
@@ -214,7 +197,132 @@
/// - an arbitary flow if \c fe is \c GEN_FLOW,
/// - an arbitary preflow if \c fe is \c PRE_FLOW,
/// - any map if \c fe is NO_FLOW.
- void preflowPhase1(FlowEnum fe);
+ void preflowPhase1(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;
+
+ 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.
+
+ 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
+
+ VecFirst first(n, INVALID);
+ NNMap next(*g, INVALID); //maybe INVALID is not needed
+ // 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.
+
+ NodeIt v;
+ for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
+ //setting each node to level n
+
+ if ( fe == NO_FLOW ) {
+ EdgeIt e;
+ for(g->first(e); g->valid(e); g->next(e)) flow->set(e,0);
+ }
+
+ switch (fe) { //computing the excess
+ case PRE_FLOW:
+ {
+ 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 )
+ {
+ next.set(v,first[lev]);
+ first[lev]=v;
+ }
+ // active[lev].push(v);
+ }
+ break;
+ }
+ case GEN_FLOW:
+ {
+ NodeIt v;
+ for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
+
+ Num exc=0;
+ 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;
+ }
+ case ZERO_FLOW:
+ case NO_FLOW:
+ {
+ NodeIt v;
+ for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
+ break;
+ }
+ }
+
+ preflowPreproc(fe, next, first,/*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;
+ }
+
+ if ( !g->valid(first[b])/*active[b].empty()*/ ) --b;
+ else {
+ end=false;
+ Node w=first[b];
+ first[b]=next[w];
+ /* Node w=active[b].top();
+ active[b].pop();*/
+ int newlevel=push(w,/*active*/next, first);
+ if ( excess[w] > 0 ) relabel(w, newlevel, /*active*/next, first, 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;
+ }
+ }
+ }
+ }
+
+ status=AFTER_PRE_FLOW_PHASE_1;
+ }
+
///Runs the second phase of the preflow algorithm.
@@ -223,26 +331,85 @@
///\ref preflowPhase2 the methods \ref flowValue, \ref minCut,
///\ref minMinCut and \ref maxMinCut give proper results.
///\pre \ref preflowPhase1 must be called before.
- void preflowPhase2();
+ void preflowPhase2()
+ {
+
+ 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
+
+
+ VecFirst first(n, INVALID);
+ NNMap next(*g, INVALID); //maybe INVALID is not needed
+ // 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 ) {
+ next.set(u,first[l]);
+ first[l]=u;
+ //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 ) {
+ next.set(u,first[l]);
+ first[l]=u;
+ //active[l].push(u);
+ }
+ }
+ }
+ }
+ b=n-2;
+
+ while ( true ) {
+
+ if ( b == 0 ) break;
+
+ if ( !g->valid(first[b])/*active[b].empty()*/ ) --b;
+ else {
+
+ Node w=first[b];
+ first[b]=next[w];
+ /* Node w=active[b].top();
+ active[b].pop();*/
+ int newlevel=push(w,next, first/*active*/);
+
+ //relabel
+ if ( excess[w] > 0 ) {
+ level.set(w,++newlevel);
+ next.set(w,first[newlevel]);
+ first[newlevel]=w;
+ //active[newlevel].push(w);
+ b=newlevel;
+ }
+ } // if stack[b] is nonempty
+ } // while(true)
+
+ status=AFTER_PRE_FLOW_PHASE_2;
+ }
- /// Starting from a flow, this method searches for an augmenting path
- /// according to the Edmonds-Karp algorithm
- /// and augments the flow on if any.
- /// The return value shows if the augmentation was succesful.
- bool augmentOnShortestPath();
- bool augmentOnShortestPath2();
-
- /// Starting from a flow, this method searches for an augmenting blocking
- /// 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.
- /// The return value show sif the augmentation was succesful.
- template<typename MutableGraph> bool augmentOnBlockingFlow();
-
- /// The same as \c augmentOnBlockingFlow<MutableGraph> but the
- /// residual graph is not constructed physically.
- /// The return value shows if the augmentation was succesful.
- bool augmentOnBlockingFlow2();
/// Returns the maximum value of a flow.
@@ -251,9 +418,9 @@
/// It can be called already after running \ref preflowPhase1.
Num flowValue() const {
Num a=0;
- FOR_EACH_INC_LOC(InEdgeIt, e, *g, t) a+=(*flow)[e];
- FOR_EACH_INC_LOC(OutEdgeIt, e, *g, t) a-=(*flow)[e];
- return a;
+ for(InEdgeIt e(*g,t);g->valid(e);G.next(e)) a+=(*flow)[e];
+ for(OutEdgeIt e(*g,t);g->valid(e);G.next(e)) a-=(*flow)[e];
+
//marci figyu: excess[t] epp ezt adja preflow 1. fazisa utan
}
@@ -714,601 +881,8 @@
level_list[newlevel]=w;
}
}
-
} //relabel
-
-
- template<typename MapGraphWrapper>
- class DistanceMap {
- protected:
- const MapGraphWrapper* g;
- typename MapGraphWrapper::template NodeMap<int> dist;
- public:
- DistanceMap(MapGraphWrapper& _g) : g(&_g), dist(*g, g->nodeNum()) { }
- void set(const typename MapGraphWrapper::Node& n, int a) {
- dist.set(n, a);
- }
- int operator[](const typename MapGraphWrapper::Node& n) const {
- 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)]);
- }
- };
-
- };
-
-
- template <typename Graph, typename Num, typename CapMap, typename FlowMap>
- void MaxFlowNoStack<Graph, Num, CapMap, FlowMap>::preflowPhase1(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;
-
- 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.
-
- 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
-
- VecFirst first(n, INVALID);
- NNMap next(*g, INVALID); //maybe INVALID is not needed
- // 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.
-
- NodeIt v;
- for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
- //setting each node to level n
-
- if ( fe == NO_FLOW ) {
- EdgeIt e;
- for(g->first(e); g->valid(e); g->next(e)) flow->set(e,0);
- }
-
- switch (fe) { //computing the excess
- case PRE_FLOW:
- {
- 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 )
- {
- next.set(v,first[lev]);
- first[lev]=v;
- }
- // active[lev].push(v);
- }
- break;
- }
- case GEN_FLOW:
- {
- NodeIt v;
- for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
-
- Num exc=0;
- 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;
- }
- case ZERO_FLOW:
- case NO_FLOW:
- {
- NodeIt v;
- for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
- break;
- }
- }
-
- preflowPreproc(fe, next, first,/*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;
- }
-
- if ( !g->valid(first[b])/*active[b].empty()*/ ) --b;
- else {
- end=false;
- Node w=first[b];
- first[b]=next[w];
- /* Node w=active[b].top();
- active[b].pop();*/
- int newlevel=push(w,/*active*/next, first);
- if ( excess[w] > 0 ) relabel(w, newlevel, /*active*/next, first, 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;
- }
- }
- }
- }
-
- status=AFTER_PRE_FLOW_PHASE_1;
- }
-
-
-
- template <typename Graph, typename Num, typename CapMap, typename FlowMap>
- void MaxFlowNoStack<Graph, Num, CapMap, FlowMap>::preflowPhase2()
- {
-
- 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
-
-
- VecFirst first(n, INVALID);
- NNMap next(*g, INVALID); //maybe INVALID is not needed
- // 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 ) {
- next.set(u,first[l]);
- first[l]=u;
- //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 ) {
- next.set(u,first[l]);
- first[l]=u;
- //active[l].push(u);
- }
- }
- }
- }
- b=n-2;
-
- while ( true ) {
-
- if ( b == 0 ) break;
-
- if ( !g->valid(first[b])/*active[b].empty()*/ ) --b;
- else {
-
- Node w=first[b];
- first[b]=next[w];
- /* Node w=active[b].top();
- active[b].pop();*/
- int newlevel=push(w,next, first/*active*/);
-
- //relabel
- if ( excess[w] > 0 ) {
- level.set(w,++newlevel);
- next.set(w,first[newlevel]);
- first[newlevel]=w;
- //active[newlevel].push(w);
- b=newlevel;
- }
- } // if stack[b] is nonempty
- } // while(true)
-
- status=AFTER_PRE_FLOW_PHASE_2;
- }
-
-
-
- template <typename Graph, typename Num, typename CapMap, typename FlowMap>
- bool MaxFlowNoStack<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath()
- {
- 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);
-
- typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
- pred.set(s, INVALID);
-
- 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; }
- }
-
- ++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);
- }
- }
-
- status=AFTER_AUGMENTING;
- return _augment;
- }
-
-
- template <typename Graph, typename Num, typename CapMap, typename FlowMap>
- bool MaxFlowNoStack<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath2()
- {
- ResGW res_graph(*g, *capacity, *flow);
- bool _augment=false;
-
- if (status!=AFTER_FAST_AUGMENTING) {
- FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
- number_of_augmentations=1;
- } else {
- ++number_of_augmentations;
- }
- TrickyReachedMap<ReachedMap>
- tricky_reached_map(level, number_of_augmentations);
- //ReachedMap level(res_graph);
-// FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
- BfsIterator<ResGW, TrickyReachedMap<ReachedMap> >
- bfs(res_graph, tricky_reached_map);
- bfs.pushAndSetReached(s);
-
- typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
- pred.set(s, INVALID);
-
- 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; }
- }
-
- ++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);
- }
- }
-
- status=AFTER_FAST_AUGMENTING;
- return _augment;
- }
-
-
- template <typename Graph, typename Num, typename CapMap, typename FlowMap>
- template<typename MutableGraph>
- bool MaxFlowNoStack<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow()
- {
- typedef MutableGraph MG;
- bool _augment=false;
-
- 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());
- }
- }
-
- 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));
- }
- }
- }
- ++bfs;
- } //computing distances from s in the residual graph
-
- 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;
- }
-
- } 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);
- }
- }
-
- }
-
- status=AFTER_AUGMENTING;
- return _augment;
- }
-
-
-
-
- template <typename Graph, typename Num, typename CapMap, typename FlowMap>
- bool MaxFlowNoStack<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow2()
- {
- bool _augment=false;
-
- 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
-
- //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))
- {
- 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
- ///\bug hugo 0.2
- (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()) {
-
- typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs);
- typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs);
-
- 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))));
- } else {
- free1.set
- (w, res_graph.resCap
- (typename ErasingResGW::OutEdgeIt(dfs)));
- }
-
- if (w==t) {
- __augment=true;
- _augment=true;
- break;
- }
- } else {
- 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);
- }
- }
-
- } //while (__augment)
-
- status=AFTER_AUGMENTING;
- return _augment;
- }
-
-
+ }; //class MaxFlow
} //namespace hugo
#endif //HUGO_MAX_FLOW_H
More information about the Lemon-commits
mailing list