diff -r b2acba449222 -r e6a156fc186d src/work/jacint/preflow.h --- a/src/work/jacint/preflow.h Thu Apr 22 13:59:37 2004 +0000 +++ b/src/work/jacint/preflow.h Thu Apr 22 14:11:28 2004 +0000 @@ -1,4 +1,10 @@ // -*- C++ -*- + +//run gyorsan tudna adni a minmincutot a 2 fazis elejen , ne vegyuk be konstruktorba egy cutmapet? +//constzero jo igy? + +//majd marci megmondja betegyem-e bfs-t meg resgraphot + /* Heuristics: 2 phase @@ -12,7 +18,8 @@ Constructors: -Preflow(Graph, Node, Node, CapMap, FlowMap) +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: @@ -29,6 +36,8 @@ void minCut(CutMap& M) : sets M to the characteristic vector of a min cut. M should be a map of bools initialized to false. +FIXME reset + */ #ifndef HUGO_PREFLOW_H @@ -44,7 +53,7 @@ template , - typename FlowMap=typename Graph::EdgeMap > + typename FlowMap=typename Graph::EdgeMap > class Preflow { typedef typename Graph::Node Node; @@ -59,13 +68,17 @@ const CapMap& capacity; FlowMap& flow; T value; + bool constzero; public: - Preflow(const Graph& _G, Node _s, Node _t, const CapMap& _capacity, - FlowMap& _flow ) : - G(_G), s(_s), t(_t), capacity(_capacity), flow(_flow) {} - + Preflow(Graph& _G, Node _s, Node _t, CapMap& _capacity, + FlowMap& _flow, bool _constzero ) : + G(_G), s(_s), t(_t), capacity(_capacity), flow(_flow), constzero(_constzero) {} + + void run() { + + value=0; //for the subsequent runs bool phase=0; //phase 0 is the 1st phase, phase 1 is the 2nd int n=G.nodeNum(); @@ -89,7 +102,7 @@ typename Graph::NodeMap level(G,n); typename Graph::NodeMap excess(G); - std::vector active(n,INVALID); + std::vector active(n-1,INVALID); typename Graph::NodeMap next(G,INVALID); //Stack of the active nodes in level i < n. //We use it in both phases. @@ -101,37 +114,37 @@ List of the nodes in level i bfs_queue; - 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); + if ( constzero ) { + + /*Reverse_bfs from t, to find the starting level.*/ + level.set(t,0); + std::queue bfs_queue; + 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); + } } } - } - - level.set(s,n); - - /* Starting flow. It is everywhere 0 at the moment. */ - OutEdgeIt e; - for(G.first(e,s); G.valid(e); G.next(e)) + //the starting flow + OutEdgeIt e; + for(G.first(e,s); G.valid(e); G.next(e)) { T c=capacity[e]; if ( c == 0 ) continue; @@ -145,6 +158,112 @@ excess.set(w, excess[w]+c); } } + } + else + { + + /* + Reverse_bfs from t in the residual graph, + to find the starting level. + */ + level.set(t,0); + std::queue bfs_queue; + 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); + } + } + + 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); + } + } + } + + + /* + Counting the excess + */ + NodeIt v; + for(G.first(v); G.valid(v); G.next(v)) { + T 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[e]; + + excess.set(v,exc); + + //putting the active nodes into the stack + int lev=level[v]; + if ( exc > 0 && lev < n ) { + next.set(v,active[lev]); + active[lev]=v; + } + } + + + //the starting flow + OutEdgeIt e; + for(G.first(e,s); G.valid(e); G.next(e)) + { + T rem=capacity[e]-flow[e]; + if ( rem == 0 ) continue; + Node w=G.head(e); + if ( level[w] < n ) { + if ( excess[w] == 0 && w!=t ) { + next.set(w,active[level[w]]); + active[level[w]]=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.head(f); + if ( level[w] < n ) { + if ( excess[w] == 0 && w!=t ) { + next.set(w,active[level[w]]); + active[level[w]]=w; + } + excess.set(w, excess[w]+flow[f]); + flow.set(f, 0); + } + } + } + + + /* End of preprocessing @@ -338,9 +457,9 @@ } //unlacing ends - //gapping starts if ( !G.valid(level_list[lev]) ) { + //gapping starts for (int i=lev; i!=k ; ) { Node v=level_list[++i]; while ( G.valid(v) ) { @@ -355,6 +474,7 @@ b=lev-1; k=b; //gapping ends + } else { if ( newlevel == n ) level.set(w,n); @@ -363,7 +483,7 @@ next.set(w,active[newlevel]); active[newlevel]=w; if ( what_heur ) b=newlevel; - if ( k < newlevel ) ++k; + if ( k < newlevel ) ++k; //now k=newlevel Node first=level_list[newlevel]; if ( G.valid(first) ) left.set(first,w); right.set(w,first); @@ -518,6 +638,20 @@ minMinCut(M); } + + void reset_target (Node _t) {t=_t;} + void reset_source (Node _s) {s=_s;} + + template + void reset_cap (_CapMap _cap) {capacity=_cap;} + + template + void reset_cap (_FlowMap _flow, bool _constzero) { + flow=_flow; + constzero=_constzero; + } + + };