7 list 'level_list' on the nodes on level i implemented by hand
8 stack 'active' on the active nodes on level i
9 runs heuristic 'highest label' for H1*n relabels
10 runs heuristic 'bound decrease' for H0*n relabels, starts with 'highest label'
12 Parameters H0 and H1 are initialized to 20 and 1.
16 Preflow(Graph, Node, Node, CapMap, FlowMap, bool) : bool must be false if
17 FlowMap is not constant zero, and should be true if it is
23 Num flowValue() : returns the value of a maximum flow
25 void minMinCut(CutMap& M) : sets M to the characteristic vector of the
26 minimum min cut. M should be a map of bools initialized to false. ??Is it OK?
28 void maxMinCut(CutMap& M) : sets M to the characteristic vector of the
29 maximum min cut. M should be a map of bools initialized to false.
31 void minCut(CutMap& M) : sets M to the characteristic vector of
32 a min cut. M should be a map of bools initialized to false.
36 #ifndef HUGO_PREFLOW_H
37 #define HUGO_PREFLOW_H
46 #include <graph_wrapper.h>
47 #include <bfs_iterator.h>
50 #include <for_each_macros.h>
55 template <typename Graph, typename Num,
56 typename CapMap=typename Graph::template EdgeMap<Num>,
57 typename FlowMap=typename Graph::template EdgeMap<Num> >
60 typedef typename Graph::Node Node;
61 typedef typename Graph::NodeIt NodeIt;
62 typedef typename Graph::OutEdgeIt OutEdgeIt;
63 typedef typename Graph::InEdgeIt InEdgeIt;
65 typedef typename std::vector<std::stack<Node> > VecStack;
66 typedef typename Graph::template NodeMap<Node> NNMap;
67 typedef typename std::vector<Node> VecNode;
72 const CapMap* capacity;
74 int n; //the number of nodes of G
75 typedef ResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;
76 typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
77 typedef typename ResGW::Edge ResGWEdge;
78 //typedef typename ResGW::template NodeMap<bool> ReachedMap;
79 typedef typename Graph::template NodeMap<int> ReachedMap;
81 //level works as a bool map in augmenting path algorithms
82 //and is used by bfs for storing reached information.
83 //In preflow, it shows levels of nodes.
84 //typename Graph::template NodeMap<int> level;
85 typename Graph::template NodeMap<Num> excess;
95 Preflow(const Graph& _G, Node _s, Node _t, const CapMap& _capacity,
97 g(&_G), s(_s), t(_t), capacity(&_capacity),
98 flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0) {}
101 preflow( ZERO_FLOW );
104 void preflow( flowEnum fe ) {
109 void preflowPhase0( flowEnum fe );
111 void preflowPhase1();
113 bool augmentOnShortestPath();
115 template<typename MutableGraph> bool augmentOnBlockingFlow();
117 bool augmentOnBlockingFlow2();
119 /// Returns the actual flow value.
120 /// More precisely, it returns the negative excess of s, thus
121 /// this works also for preflows.
124 FOR_EACH_INC_LOC(OutEdgeIt, e, *g, s) a+=(*flow)[e];
125 FOR_EACH_INC_LOC(InEdgeIt, e, *g, s) a-=(*flow)[e];
129 //should be used only between preflowPhase0 and preflowPhase1
130 template<typename _CutMap>
131 void actMinCut(_CutMap& M) {
133 for(g->first(v); g->valid(v); g->next(v))
134 if ( level[v] < n ) {
144 Returns the minimum min cut, by a bfs from s in the residual graph.
146 template<typename _CutMap>
147 void minMinCut(_CutMap& M) {
149 std::queue<Node> queue;
154 while (!queue.empty()) {
155 Node w=queue.front();
159 for(g->first(e,w) ; g->valid(e); g->next(e)) {
161 if (!M[v] && (*flow)[e] < (*capacity)[e] ) {
168 for(g->first(f,w) ; g->valid(f); g->next(f)) {
170 if (!M[v] && (*flow)[f] > 0 ) {
181 Returns the maximum min cut, by a reverse bfs
182 from t in the residual graph.
185 template<typename _CutMap>
186 void maxMinCut(_CutMap& M) {
189 for(g->first(v) ; g->valid(v); g->next(v)) {
193 std::queue<Node> queue;
198 while (!queue.empty()) {
199 Node w=queue.front();
204 for(g->first(e,w) ; g->valid(e); g->next(e)) {
206 if (M[v] && (*flow)[e] < (*capacity)[e] ) {
213 for(g->first(f,w) ; g->valid(f); g->next(f)) {
215 if (M[v] && (*flow)[f] > 0 ) {
224 template<typename CutMap>
225 void minCut(CutMap& M) {
229 void resetTarget(Node _t) {t=_t;}
230 void resetSource(Node _s) {s=_s;}
232 void resetCap(const CapMap& _cap) {
236 void resetFlow(FlowMap& _flow) {
243 int push(Node w, VecStack& active) {
247 int newlevel=n; //bound on the next level of w
250 for(g->first(e,w); g->valid(e); g->next(e)) {
252 if ( (*flow)[e] >= (*capacity)[e] ) continue;
255 if( lev > level[v] ) { //Push is allowed now
257 if ( excess[v]<=0 && v!=t && v!=s ) {
259 active[lev_v].push(v);
262 Num cap=(*capacity)[e];
266 if ( remcap >= exc ) { //A nonsaturating push.
268 flow->set(e, flo+exc);
269 excess.set(v, excess[v]+exc);
273 } else { //A saturating push.
275 excess.set(v, excess[v]+remcap);
278 } else if ( newlevel > level[v] ) newlevel = level[v];
283 for(g->first(e,w); g->valid(e); g->next(e)) {
285 if( (*flow)[e] <= 0 ) continue;
288 if( lev > level[v] ) { //Push is allowed now
290 if ( excess[v]<=0 && v!=t && v!=s ) {
292 active[lev_v].push(v);
297 if ( flo >= exc ) { //A nonsaturating push.
299 flow->set(e, flo-exc);
300 excess.set(v, excess[v]+exc);
303 } else { //A saturating push.
305 excess.set(v, excess[v]+flo);
309 } else if ( newlevel > level[v] ) newlevel = level[v];
312 } // if w still has excess after the out edge for cycle
320 void preflowPreproc ( flowEnum fe, VecStack& active,
321 VecNode& level_list, NNMap& left, NNMap& right ) {
323 std::queue<Node> bfs_queue;
328 //Reverse_bfs from t, to find the starting level.
332 while (!bfs_queue.empty()) {
334 Node v=bfs_queue.front();
339 for(g->first(e,v); g->valid(e); g->next(e)) {
341 if ( level[w] == n && w != s ) {
343 Node first=level_list[l];
344 if ( g->valid(first) ) left.set(first,w);
354 for(g->first(e,s); g->valid(e); g->next(e))
356 Num c=(*capacity)[e];
357 if ( c <= 0 ) continue;
359 if ( level[w] < n ) {
360 if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
362 excess.set(w, excess[w]+c);
371 //Reverse_bfs from t in the residual graph,
372 //to find the starting level.
376 while (!bfs_queue.empty()) {
378 Node v=bfs_queue.front();
383 for(g->first(e,v); g->valid(e); g->next(e)) {
384 if ( (*capacity)[e] <= (*flow)[e] ) continue;
386 if ( level[w] == n && w != s ) {
388 Node first=level_list[l];
389 if ( g->valid(first) ) left.set(first,w);
397 for(g->first(f,v); g->valid(f); g->next(f)) {
398 if ( 0 >= (*flow)[f] ) continue;
400 if ( level[w] == n && w != s ) {
402 Node first=level_list[l];
403 if ( g->valid(first) ) left.set(first,w);
414 for(g->first(e,s); g->valid(e); g->next(e))
416 Num rem=(*capacity)[e]-(*flow)[e];
417 if ( rem <= 0 ) continue;
419 if ( level[w] < n ) {
420 if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
421 flow->set(e, (*capacity)[e]);
422 excess.set(w, excess[w]+rem);
427 for(g->first(f,s); g->valid(f); g->next(f))
429 if ( (*flow)[f] <= 0 ) continue;
431 if ( level[w] < n ) {
432 if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
433 excess.set(w, excess[w]+(*flow)[f]);
444 void relabel(Node w, int newlevel, VecStack& active,
445 VecNode& level_list, NNMap& left,
446 NNMap& right, int& b, int& k, bool what_heur )
451 Node right_n=right[w];
455 if ( g->valid(right_n) ) {
456 if ( g->valid(left_n) ) {
457 right.set(left_n, right_n);
458 left.set(right_n, left_n);
460 level_list[lev]=right_n;
461 left.set(right_n, INVALID);
464 if ( g->valid(left_n) ) {
465 right.set(left_n, INVALID);
467 level_list[lev]=INVALID;
472 if ( !g->valid(level_list[lev]) ) {
475 for (int i=lev; i!=k ; ) {
476 Node v=level_list[++i];
477 while ( g->valid(v) ) {
481 level_list[i]=INVALID;
483 while ( !active[i].empty() ) {
484 active[i].pop(); //FIXME: ezt szebben kene
496 if ( newlevel == n ) level.set(w,n);
498 level.set(w,++newlevel);
499 active[newlevel].push(w);
500 if ( what_heur ) b=newlevel;
501 if ( k < newlevel ) ++k; //now k=newlevel
502 Node first=level_list[newlevel];
503 if ( g->valid(first) ) left.set(first,w);
506 level_list[newlevel]=w;
513 template<typename MapGraphWrapper>
516 const MapGraphWrapper* g;
517 typename MapGraphWrapper::template NodeMap<int> dist;
519 DistanceMap(MapGraphWrapper& _g) : g(&_g), dist(*g, g->nodeNum()) { }
520 void set(const typename MapGraphWrapper::Node& n, int a) {
523 int operator[](const typename MapGraphWrapper::Node& n)
525 // int get(const typename MapGraphWrapper::Node& n) const {
527 // bool get(const typename MapGraphWrapper::Edge& e) const {
528 // return (dist.get(g->tail(e))<dist.get(g->head(e))); }
529 bool operator[](const typename MapGraphWrapper::Edge& e) const {
530 return (dist[g->tail(e)]<dist[g->head(e)]);
537 template <typename Graph, typename Num, typename CapMap, typename FlowMap>
538 void Preflow<Graph, Num, CapMap, FlowMap>::preflowPhase0( flowEnum fe )
541 int heur0=(int)(H0*n); //time while running 'bound decrease'
542 int heur1=(int)(H1*n); //time while running 'highest label'
543 int heur=heur1; //starting time interval (#of relabels)
547 //It is 0 in case 'bound decrease' and 1 in case 'highest label'
550 //Needed for 'bound decrease', true means no active nodes are above bound b.
552 int k=n-2; //bound on the highest level under n containing a node
553 int b=k; //bound on the highest level under n of an active node
557 NNMap left(*g, INVALID);
558 NNMap right(*g, INVALID);
559 VecNode level_list(n,INVALID);
560 //List of the nodes in level i<n, set to n.
563 for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
564 //setting each node to level n
569 //counting the excess
571 for(g->first(v); g->valid(v); g->next(v)) {
575 for(g->first(e,v); g->valid(e); g->next(e)) exc+=(*flow)[e];
577 for(g->first(f,v); g->valid(f); g->next(f)) exc-=(*flow)[f];
581 //putting the active nodes into the stack
583 if ( exc > 0 && lev < n && v != t ) active[lev].push(v);
589 //Counting the excess of t
593 for(g->first(e,t); g->valid(e); g->next(e)) exc+=(*flow)[e];
595 for(g->first(f,t); g->valid(f); g->next(f)) exc-=(*flow)[f];
605 preflowPreproc( fe, active, level_list, left, right );
606 //End of preprocessing
609 //Push/relabel on the highest level active nodes.
612 if ( !what_heur && !end && k > 0 ) {
618 if ( active[b].empty() ) --b;
621 Node w=active[b].top();
623 int newlevel=push(w,active);
624 if ( excess[w] > 0 ) relabel(w, newlevel, active, level_list,
625 left, right, b, k, what_heur);
628 if ( numrelabel >= heur ) {
646 template <typename Graph, typename Num, typename CapMap, typename FlowMap>
647 void Preflow<Graph, Num, CapMap, FlowMap>::preflowPhase1()
650 int k=n-2; //bound on the highest level under n containing a node
651 int b=k; //bound on the highest level under n of an active node
655 std::queue<Node> bfs_queue;
658 while (!bfs_queue.empty()) {
660 Node v=bfs_queue.front();
665 for(g->first(e,v); g->valid(e); g->next(e)) {
666 if ( (*capacity)[e] <= (*flow)[e] ) continue;
668 if ( level[u] >= n ) {
671 if ( excess[u] > 0 ) active[l].push(u);
676 for(g->first(f,v); g->valid(f); g->next(f)) {
677 if ( 0 >= (*flow)[f] ) continue;
679 if ( level[u] >= n ) {
682 if ( excess[u] > 0 ) active[l].push(u);
692 if ( active[b].empty() ) --b;
694 Node w=active[b].top();
696 int newlevel=push(w,active);
699 if ( excess[w] > 0 ) {
700 level.set(w,++newlevel);
701 active[newlevel].push(w);
704 } // if stack[b] is nonempty
710 template <typename Graph, typename Num, typename CapMap, typename FlowMap>
711 bool Preflow<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath()
713 ResGW res_graph(*g, *capacity, *flow);
716 //ReachedMap level(res_graph);
717 FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
718 BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
719 bfs.pushAndSetReached(s);
721 typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
722 pred.set(s, INVALID);
724 typename ResGW::template NodeMap<Num> free(res_graph);
726 //searching for augmenting path
727 while ( !bfs.finished() ) {
728 ResGWOutEdgeIt e=bfs;
729 if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
730 Node v=res_graph.tail(e);
731 Node w=res_graph.head(e);
733 if (res_graph.valid(pred[v])) {
734 free.set(w, std::min(free[v], res_graph.resCap(e)));
736 free.set(w, res_graph.resCap(e));
738 if (res_graph.head(e)==t) { _augment=true; break; }
742 } //end of searching augmenting path
746 Num augment_value=free[t];
747 while (res_graph.valid(pred[n])) {
749 res_graph.augment(e, augment_value);
765 template <typename Graph, typename Num, typename CapMap, typename FlowMap>
766 template<typename MutableGraph>
767 bool Preflow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow()
769 typedef MutableGraph MG;
772 ResGW res_graph(*g, *capacity, *flow);
774 //bfs for distances on the residual graph
775 //ReachedMap level(res_graph);
776 FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
777 BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
778 bfs.pushAndSetReached(s);
779 typename ResGW::template NodeMap<int>
780 dist(res_graph); //filled up with 0's
782 //F will contain the physical copy of the residual graph
783 //with the set of edges which are on shortest paths
785 typename ResGW::template NodeMap<typename MG::Node>
786 res_graph_to_F(res_graph);
788 typename ResGW::NodeIt n;
789 for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
790 res_graph_to_F.set(n, F.addNode());
794 typename MG::Node sF=res_graph_to_F[s];
795 typename MG::Node tF=res_graph_to_F[t];
796 typename MG::template EdgeMap<ResGWEdge> original_edge(F);
797 typename MG::template EdgeMap<Num> residual_capacity(F);
799 while ( !bfs.finished() ) {
800 ResGWOutEdgeIt e=bfs;
801 if (res_graph.valid(e)) {
802 if (bfs.isBNodeNewlyReached()) {
803 dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
804 typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
805 original_edge.update();
806 original_edge.set(f, e);
807 residual_capacity.update();
808 residual_capacity.set(f, res_graph.resCap(e));
810 if (dist[res_graph.head(e)]==(dist[res_graph.tail(e)]+1)) {
811 typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
812 original_edge.update();
813 original_edge.set(f, e);
814 residual_capacity.update();
815 residual_capacity.set(f, res_graph.resCap(e));
820 } //computing distances from s in the residual graph
826 //computing blocking flow with dfs
827 DfsIterator< MG, typename MG::template NodeMap<bool> > dfs(F);
828 typename MG::template NodeMap<typename MG::Edge> pred(F);
829 pred.set(sF, INVALID);
830 //invalid iterators for sources
832 typename MG::template NodeMap<Num> free(F);
834 dfs.pushAndSetReached(sF);
835 while (!dfs.finished()) {
837 if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
838 if (dfs.isBNodeNewlyReached()) {
839 typename MG::Node v=F.aNode(dfs);
840 typename MG::Node w=F.bNode(dfs);
842 if (F.valid(pred[v])) {
843 free.set(w, std::min(free[v], residual_capacity[dfs]));
845 free.set(w, residual_capacity[dfs]);
854 F.erase(/*typename MG::OutEdgeIt*/(dfs));
860 typename MG::Node n=tF;
861 Num augment_value=free[tF];
862 while (F.valid(pred[n])) {
863 typename MG::Edge e=pred[n];
864 res_graph.augment(original_edge[e], augment_value);
866 if (residual_capacity[e]==augment_value)
869 residual_capacity.set(e, residual_capacity[e]-augment_value);
883 template <typename Graph, typename Num, typename CapMap, typename FlowMap>
884 bool Preflow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow2()
888 ResGW res_graph(*g, *capacity, *flow);
890 //ReachedMap level(res_graph);
891 FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
892 BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
894 bfs.pushAndSetReached(s);
895 DistanceMap<ResGW> dist(res_graph);
896 while ( !bfs.finished() ) {
897 ResGWOutEdgeIt e=bfs;
898 if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
899 dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
902 } //computing distances from s in the residual graph
904 //Subgraph containing the edges on some shortest paths
905 ConstMap<typename ResGW::Node, bool> true_map(true);
906 typedef SubGraphWrapper<ResGW, ConstMap<typename ResGW::Node, bool>,
907 DistanceMap<ResGW> > FilterResGW;
908 FilterResGW filter_res_graph(res_graph, true_map, dist);
910 //Subgraph, which is able to delete edges which are already
912 typename FilterResGW::template NodeMap<typename FilterResGW::OutEdgeIt>
913 first_out_edges(filter_res_graph);
914 typename FilterResGW::NodeIt v;
915 for(filter_res_graph.first(v); filter_res_graph.valid(v);
916 filter_res_graph.next(v))
918 typename FilterResGW::OutEdgeIt e;
919 filter_res_graph.first(e, v);
920 first_out_edges.set(v, e);
922 typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
923 template NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
924 ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
931 //computing blocking flow with dfs
932 DfsIterator< ErasingResGW,
933 typename ErasingResGW::template NodeMap<bool> >
934 dfs(erasing_res_graph);
935 typename ErasingResGW::
936 template NodeMap<typename ErasingResGW::OutEdgeIt>
937 pred(erasing_res_graph);
938 pred.set(s, INVALID);
939 //invalid iterators for sources
941 typename ErasingResGW::template NodeMap<Num>
942 free1(erasing_res_graph);
944 dfs.pushAndSetReached(
945 typename ErasingResGW::Node(
946 typename FilterResGW::Node(
947 typename ResGW::Node(s)
951 while (!dfs.finished()) {
953 if (erasing_res_graph.valid(
954 typename ErasingResGW::OutEdgeIt(dfs)))
956 if (dfs.isBNodeNewlyReached()) {
958 typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs);
959 typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs);
961 pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs));
962 if (erasing_res_graph.valid(pred[v])) {
963 free1.set(w, std::min(free1[v], res_graph.resCap(
964 typename ErasingResGW::OutEdgeIt(dfs))));
966 free1.set(w, res_graph.resCap(
967 typename ErasingResGW::OutEdgeIt(dfs)));
976 erasing_res_graph.erase(dfs);
982 typename ErasingResGW::Node n=typename FilterResGW::Node(typename ResGW::Node(t));
983 // typename ResGW::NodeMap<Num> a(res_graph);
984 // typename ResGW::Node b;
986 // typename FilterResGW::NodeMap<Num> a1(filter_res_graph);
987 // typename FilterResGW::Node b1;
989 // typename ErasingResGW::NodeMap<Num> a2(erasing_res_graph);
990 // typename ErasingResGW::Node b2;
992 Num augment_value=free1[n];
993 while (erasing_res_graph.valid(pred[n])) {
994 typename ErasingResGW::OutEdgeIt e=pred[n];
995 res_graph.augment(e, augment_value);
996 n=erasing_res_graph.tail(e);
997 if (res_graph.resCap(e)==0)
998 erasing_res_graph.erase(e);
1002 } //while (__augment)
1012 #endif //HUGO_PREFLOW_H