A bipartite graph template can be used as BipartiteGraph<ListGraph>.
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_MAX_FLOW_H
37 #define HUGO_MAX_FLOW_H
46 #include <graph_wrapper.h>
47 #include <bfs_iterator.h>
50 #include <for_each_macros.h>
53 /// \brief Dimacs file format reader.
58 // ///\author Marton Makai, Jacint Szabo
59 /// A class for computing max flows and related quantities.
60 template <typename Graph, typename Num,
61 typename CapMap=typename Graph::template EdgeMap<Num>,
62 typename FlowMap=typename Graph::template EdgeMap<Num> >
65 typedef typename Graph::Node Node;
66 typedef typename Graph::NodeIt NodeIt;
67 typedef typename Graph::OutEdgeIt OutEdgeIt;
68 typedef typename Graph::InEdgeIt InEdgeIt;
70 typedef typename std::vector<std::stack<Node> > VecStack;
71 typedef typename Graph::template NodeMap<Node> NNMap;
72 typedef typename std::vector<Node> VecNode;
77 const CapMap* capacity;
79 int n; //the number of nodes of G
80 typedef ResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;
81 typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
82 typedef typename ResGW::Edge ResGWEdge;
83 //typedef typename ResGW::template NodeMap<bool> ReachedMap;
84 typedef typename Graph::template NodeMap<int> ReachedMap;
86 //level works as a bool map in augmenting path algorithms
87 //and is used by bfs for storing reached information.
88 //In preflow, it shows levels of nodes.
89 //typename Graph::template NodeMap<int> level;
90 typename Graph::template NodeMap<Num> excess;
94 ///\todo Document this
101 MaxFlow(const Graph& _G, Node _s, Node _t, const CapMap& _capacity,
103 g(&_G), s(_s), t(_t), capacity(&_capacity),
104 flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0) {}
106 /// A max flow algorithm is run.
107 ///\pre the flow have to be 0 at the beginning.
112 /// A preflow algorithm is run.
113 ///\pre The initial edge-map have to be a
114 /// zero flow if \c fe is \c ZERO_FLOW,
115 /// a flow if \c fe is \c GEN_FLOW,
116 /// and a pre-flow it is \c PREFLOW.
117 void preflow(flowEnum fe) {
122 /// Run the first phase of preflow, starting from a 0 flow, from a flow,
123 /// or from a preflow, according to \c fe.
124 void preflowPhase0( flowEnum fe );
126 /// Second phase of preflow.
127 void preflowPhase1();
129 /// Starting from a flow, this method searches for an augmenting path
130 /// according to the Edmonds-Karp algorithm
131 /// and augments the flow on if any.
132 /// The return value shows if the augmentation was succesful.
133 bool augmentOnShortestPath();
135 /// Starting from a flow, this method searches for an augmenting blockin
136 /// flow according to Dinits' algorithm and augments the flow on if any.
137 /// The blocking flow is computed in a physically constructed
138 /// residual graph of type \c Mutablegraph.
139 /// The return value show sif the augmentation was succesful.
140 template<typename MutableGraph> bool augmentOnBlockingFlow();
142 /// The same as \c augmentOnBlockingFlow<MutableGraph> but the
143 /// residual graph is not constructed physically.
144 /// The return value shows if the augmentation was succesful.
145 bool augmentOnBlockingFlow2();
147 /// Returns the actual flow value.
148 /// More precisely, it returns the negative excess of s, thus
149 /// this works also for preflows.
152 FOR_EACH_INC_LOC(OutEdgeIt, e, *g, s) a+=(*flow)[e];
153 FOR_EACH_INC_LOC(InEdgeIt, e, *g, s) a-=(*flow)[e];
157 /// Should be used between preflowPhase0 and preflowPhase1.
158 ///\todo We have to make some status variable which shows the actual state
159 /// of the class. This enables us to determine which methods are valid
160 /// for MinCut computation
161 template<typename _CutMap>
162 void actMinCut(_CutMap& M) {
164 for(g->first(v); g->valid(v); g->next(v)) {
165 if ( level[v] < n ) {
173 /// The unique inclusionwise minimum cut is computed by
174 /// processing a bfs from s in the residual graph.
175 ///\pre flow have to be a max flow otherwise it will the whole node-set.
176 template<typename _CutMap>
177 void minMinCut(_CutMap& M) {
179 std::queue<Node> queue;
184 while (!queue.empty()) {
185 Node w=queue.front();
189 for(g->first(e,w) ; g->valid(e); g->next(e)) {
191 if (!M[v] && (*flow)[e] < (*capacity)[e] ) {
198 for(g->first(f,w) ; g->valid(f); g->next(f)) {
200 if (!M[v] && (*flow)[f] > 0 ) {
209 /// The unique inclusionwise maximum cut is computed by
210 /// processing a reverse bfs from t in the residual graph.
211 ///\pre flow have to be a max flow otherwise it will be empty.
212 template<typename _CutMap>
213 void maxMinCut(_CutMap& M) {
216 for(g->first(v) ; g->valid(v); g->next(v)) {
220 std::queue<Node> queue;
225 while (!queue.empty()) {
226 Node w=queue.front();
231 for(g->first(e,w) ; g->valid(e); g->next(e)) {
233 if (M[v] && (*flow)[e] < (*capacity)[e] ) {
240 for(g->first(f,w) ; g->valid(f); g->next(f)) {
242 if (M[v] && (*flow)[f] > 0 ) {
251 /// A minimum cut is computed.
252 template<typename CutMap>
253 void minCut(CutMap& M) { minMinCut(M); }
256 void resetSource(Node _s) { s=_s; }
258 void resetTarget(Node _t) { t=_t; }
260 /// capacity-map is changed.
261 void resetCap(const CapMap& _cap) { capacity=&_cap; }
263 /// flow-map is changed.
264 void resetFlow(FlowMap& _flow) { flow=&_flow; }
269 int push(Node w, VecStack& active) {
273 int newlevel=n; //bound on the next level of w
276 for(g->first(e,w); g->valid(e); g->next(e)) {
278 if ( (*flow)[e] >= (*capacity)[e] ) continue;
281 if( lev > level[v] ) { //Push is allowed now
283 if ( excess[v]<=0 && v!=t && v!=s ) {
285 active[lev_v].push(v);
288 Num cap=(*capacity)[e];
292 if ( remcap >= exc ) { //A nonsaturating push.
294 flow->set(e, flo+exc);
295 excess.set(v, excess[v]+exc);
299 } else { //A saturating push.
301 excess.set(v, excess[v]+remcap);
304 } else if ( newlevel > level[v] ) newlevel = level[v];
309 for(g->first(e,w); g->valid(e); g->next(e)) {
311 if( (*flow)[e] <= 0 ) continue;
314 if( lev > level[v] ) { //Push is allowed now
316 if ( excess[v]<=0 && v!=t && v!=s ) {
318 active[lev_v].push(v);
323 if ( flo >= exc ) { //A nonsaturating push.
325 flow->set(e, flo-exc);
326 excess.set(v, excess[v]+exc);
329 } else { //A saturating push.
331 excess.set(v, excess[v]+flo);
335 } else if ( newlevel > level[v] ) newlevel = level[v];
338 } // if w still has excess after the out edge for cycle
346 void preflowPreproc ( flowEnum fe, VecStack& active,
347 VecNode& level_list, NNMap& left, NNMap& right ) {
349 std::queue<Node> bfs_queue;
354 //Reverse_bfs from t, to find the starting level.
358 while (!bfs_queue.empty()) {
360 Node v=bfs_queue.front();
365 for(g->first(e,v); g->valid(e); g->next(e)) {
367 if ( level[w] == n && w != s ) {
369 Node first=level_list[l];
370 if ( g->valid(first) ) left.set(first,w);
380 for(g->first(e,s); g->valid(e); g->next(e))
382 Num c=(*capacity)[e];
383 if ( c <= 0 ) continue;
385 if ( level[w] < n ) {
386 if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
388 excess.set(w, excess[w]+c);
397 //Reverse_bfs from t in the residual graph,
398 //to find the starting level.
402 while (!bfs_queue.empty()) {
404 Node v=bfs_queue.front();
409 for(g->first(e,v); g->valid(e); g->next(e)) {
410 if ( (*capacity)[e] <= (*flow)[e] ) continue;
412 if ( level[w] == n && w != s ) {
414 Node first=level_list[l];
415 if ( g->valid(first) ) left.set(first,w);
423 for(g->first(f,v); g->valid(f); g->next(f)) {
424 if ( 0 >= (*flow)[f] ) continue;
426 if ( level[w] == n && w != s ) {
428 Node first=level_list[l];
429 if ( g->valid(first) ) left.set(first,w);
440 for(g->first(e,s); g->valid(e); g->next(e))
442 Num rem=(*capacity)[e]-(*flow)[e];
443 if ( rem <= 0 ) continue;
445 if ( level[w] < n ) {
446 if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
447 flow->set(e, (*capacity)[e]);
448 excess.set(w, excess[w]+rem);
453 for(g->first(f,s); g->valid(f); g->next(f))
455 if ( (*flow)[f] <= 0 ) continue;
457 if ( level[w] < n ) {
458 if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
459 excess.set(w, excess[w]+(*flow)[f]);
470 void relabel(Node w, int newlevel, VecStack& active,
471 VecNode& level_list, NNMap& left,
472 NNMap& right, int& b, int& k, bool what_heur )
477 Node right_n=right[w];
481 if ( g->valid(right_n) ) {
482 if ( g->valid(left_n) ) {
483 right.set(left_n, right_n);
484 left.set(right_n, left_n);
486 level_list[lev]=right_n;
487 left.set(right_n, INVALID);
490 if ( g->valid(left_n) ) {
491 right.set(left_n, INVALID);
493 level_list[lev]=INVALID;
498 if ( !g->valid(level_list[lev]) ) {
501 for (int i=lev; i!=k ; ) {
502 Node v=level_list[++i];
503 while ( g->valid(v) ) {
507 level_list[i]=INVALID;
509 while ( !active[i].empty() ) {
510 active[i].pop(); //FIXME: ezt szebben kene
522 if ( newlevel == n ) level.set(w,n);
524 level.set(w,++newlevel);
525 active[newlevel].push(w);
526 if ( what_heur ) b=newlevel;
527 if ( k < newlevel ) ++k; //now k=newlevel
528 Node first=level_list[newlevel];
529 if ( g->valid(first) ) left.set(first,w);
532 level_list[newlevel]=w;
539 template<typename MapGraphWrapper>
542 const MapGraphWrapper* g;
543 typename MapGraphWrapper::template NodeMap<int> dist;
545 DistanceMap(MapGraphWrapper& _g) : g(&_g), dist(*g, g->nodeNum()) { }
546 void set(const typename MapGraphWrapper::Node& n, int a) {
549 int operator[](const typename MapGraphWrapper::Node& n)
551 // int get(const typename MapGraphWrapper::Node& n) const {
553 // bool get(const typename MapGraphWrapper::Edge& e) const {
554 // return (dist.get(g->tail(e))<dist.get(g->head(e))); }
555 bool operator[](const typename MapGraphWrapper::Edge& e) const {
556 return (dist[g->tail(e)]<dist[g->head(e)]);
563 template <typename Graph, typename Num, typename CapMap, typename FlowMap>
564 void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase0( flowEnum fe )
567 int heur0=(int)(H0*n); //time while running 'bound decrease'
568 int heur1=(int)(H1*n); //time while running 'highest label'
569 int heur=heur1; //starting time interval (#of relabels)
573 //It is 0 in case 'bound decrease' and 1 in case 'highest label'
576 //Needed for 'bound decrease', true means no active nodes are above bound b.
578 int k=n-2; //bound on the highest level under n containing a node
579 int b=k; //bound on the highest level under n of an active node
583 NNMap left(*g, INVALID);
584 NNMap right(*g, INVALID);
585 VecNode level_list(n,INVALID);
586 //List of the nodes in level i<n, set to n.
589 for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
590 //setting each node to level n
595 //counting the excess
597 for(g->first(v); g->valid(v); g->next(v)) {
601 for(g->first(e,v); g->valid(e); g->next(e)) exc+=(*flow)[e];
603 for(g->first(f,v); g->valid(f); g->next(f)) exc-=(*flow)[f];
607 //putting the active nodes into the stack
609 if ( exc > 0 && lev < n && v != t ) active[lev].push(v);
615 //Counting the excess of t
619 for(g->first(e,t); g->valid(e); g->next(e)) exc+=(*flow)[e];
621 for(g->first(f,t); g->valid(f); g->next(f)) exc-=(*flow)[f];
631 preflowPreproc( fe, active, level_list, left, right );
632 //End of preprocessing
635 //Push/relabel on the highest level active nodes.
638 if ( !what_heur && !end && k > 0 ) {
644 if ( active[b].empty() ) --b;
647 Node w=active[b].top();
649 int newlevel=push(w,active);
650 if ( excess[w] > 0 ) relabel(w, newlevel, active, level_list,
651 left, right, b, k, what_heur);
654 if ( numrelabel >= heur ) {
672 template <typename Graph, typename Num, typename CapMap, typename FlowMap>
673 void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase1()
676 int k=n-2; //bound on the highest level under n containing a node
677 int b=k; //bound on the highest level under n of an active node
681 std::queue<Node> bfs_queue;
684 while (!bfs_queue.empty()) {
686 Node v=bfs_queue.front();
691 for(g->first(e,v); g->valid(e); g->next(e)) {
692 if ( (*capacity)[e] <= (*flow)[e] ) continue;
694 if ( level[u] >= n ) {
697 if ( excess[u] > 0 ) active[l].push(u);
702 for(g->first(f,v); g->valid(f); g->next(f)) {
703 if ( 0 >= (*flow)[f] ) continue;
705 if ( level[u] >= n ) {
708 if ( excess[u] > 0 ) active[l].push(u);
718 if ( active[b].empty() ) --b;
720 Node w=active[b].top();
722 int newlevel=push(w,active);
725 if ( excess[w] > 0 ) {
726 level.set(w,++newlevel);
727 active[newlevel].push(w);
730 } // if stack[b] is nonempty
736 template <typename Graph, typename Num, typename CapMap, typename FlowMap>
737 bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath()
739 ResGW res_graph(*g, *capacity, *flow);
742 //ReachedMap level(res_graph);
743 FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
744 BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
745 bfs.pushAndSetReached(s);
747 typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
748 pred.set(s, INVALID);
750 typename ResGW::template NodeMap<Num> free(res_graph);
752 //searching for augmenting path
753 while ( !bfs.finished() ) {
754 ResGWOutEdgeIt e=bfs;
755 if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
756 Node v=res_graph.tail(e);
757 Node w=res_graph.head(e);
759 if (res_graph.valid(pred[v])) {
760 free.set(w, std::min(free[v], res_graph.resCap(e)));
762 free.set(w, res_graph.resCap(e));
764 if (res_graph.head(e)==t) { _augment=true; break; }
768 } //end of searching augmenting path
772 Num augment_value=free[t];
773 while (res_graph.valid(pred[n])) {
775 res_graph.augment(e, augment_value);
791 template <typename Graph, typename Num, typename CapMap, typename FlowMap>
792 template<typename MutableGraph>
793 bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow()
795 typedef MutableGraph MG;
798 ResGW res_graph(*g, *capacity, *flow);
800 //bfs for distances on the residual graph
801 //ReachedMap level(res_graph);
802 FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
803 BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
804 bfs.pushAndSetReached(s);
805 typename ResGW::template NodeMap<int>
806 dist(res_graph); //filled up with 0's
808 //F will contain the physical copy of the residual graph
809 //with the set of edges which are on shortest paths
811 typename ResGW::template NodeMap<typename MG::Node>
812 res_graph_to_F(res_graph);
814 typename ResGW::NodeIt n;
815 for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
816 res_graph_to_F.set(n, F.addNode());
820 typename MG::Node sF=res_graph_to_F[s];
821 typename MG::Node tF=res_graph_to_F[t];
822 typename MG::template EdgeMap<ResGWEdge> original_edge(F);
823 typename MG::template EdgeMap<Num> residual_capacity(F);
825 while ( !bfs.finished() ) {
826 ResGWOutEdgeIt e=bfs;
827 if (res_graph.valid(e)) {
828 if (bfs.isBNodeNewlyReached()) {
829 dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
830 typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
831 original_edge.update();
832 original_edge.set(f, e);
833 residual_capacity.update();
834 residual_capacity.set(f, res_graph.resCap(e));
836 if (dist[res_graph.head(e)]==(dist[res_graph.tail(e)]+1)) {
837 typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
838 original_edge.update();
839 original_edge.set(f, e);
840 residual_capacity.update();
841 residual_capacity.set(f, res_graph.resCap(e));
846 } //computing distances from s in the residual graph
852 //computing blocking flow with dfs
853 DfsIterator< MG, typename MG::template NodeMap<bool> > dfs(F);
854 typename MG::template NodeMap<typename MG::Edge> pred(F);
855 pred.set(sF, INVALID);
856 //invalid iterators for sources
858 typename MG::template NodeMap<Num> free(F);
860 dfs.pushAndSetReached(sF);
861 while (!dfs.finished()) {
863 if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
864 if (dfs.isBNodeNewlyReached()) {
865 typename MG::Node v=F.aNode(dfs);
866 typename MG::Node w=F.bNode(dfs);
868 if (F.valid(pred[v])) {
869 free.set(w, std::min(free[v], residual_capacity[dfs]));
871 free.set(w, residual_capacity[dfs]);
880 F.erase(/*typename MG::OutEdgeIt*/(dfs));
886 typename MG::Node n=tF;
887 Num augment_value=free[tF];
888 while (F.valid(pred[n])) {
889 typename MG::Edge e=pred[n];
890 res_graph.augment(original_edge[e], augment_value);
892 if (residual_capacity[e]==augment_value)
895 residual_capacity.set(e, residual_capacity[e]-augment_value);
909 template <typename Graph, typename Num, typename CapMap, typename FlowMap>
910 bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow2()
914 ResGW res_graph(*g, *capacity, *flow);
916 //ReachedMap level(res_graph);
917 FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
918 BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
920 bfs.pushAndSetReached(s);
921 DistanceMap<ResGW> dist(res_graph);
922 while ( !bfs.finished() ) {
923 ResGWOutEdgeIt e=bfs;
924 if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
925 dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
928 } //computing distances from s in the residual graph
930 //Subgraph containing the edges on some shortest paths
931 ConstMap<typename ResGW::Node, bool> true_map(true);
932 typedef SubGraphWrapper<ResGW, ConstMap<typename ResGW::Node, bool>,
933 DistanceMap<ResGW> > FilterResGW;
934 FilterResGW filter_res_graph(res_graph, true_map, dist);
936 //Subgraph, which is able to delete edges which are already
938 typename FilterResGW::template NodeMap<typename FilterResGW::OutEdgeIt>
939 first_out_edges(filter_res_graph);
940 typename FilterResGW::NodeIt v;
941 for(filter_res_graph.first(v); filter_res_graph.valid(v);
942 filter_res_graph.next(v))
944 typename FilterResGW::OutEdgeIt e;
945 filter_res_graph.first(e, v);
946 first_out_edges.set(v, e);
948 typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
949 template NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
950 ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
957 //computing blocking flow with dfs
958 DfsIterator< ErasingResGW,
959 typename ErasingResGW::template NodeMap<bool> >
960 dfs(erasing_res_graph);
961 typename ErasingResGW::
962 template NodeMap<typename ErasingResGW::OutEdgeIt>
963 pred(erasing_res_graph);
964 pred.set(s, INVALID);
965 //invalid iterators for sources
967 typename ErasingResGW::template NodeMap<Num>
968 free1(erasing_res_graph);
970 dfs.pushAndSetReached(
971 typename ErasingResGW::Node(
972 typename FilterResGW::Node(
973 typename ResGW::Node(s)
977 while (!dfs.finished()) {
979 if (erasing_res_graph.valid(
980 typename ErasingResGW::OutEdgeIt(dfs)))
982 if (dfs.isBNodeNewlyReached()) {
984 typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs);
985 typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs);
987 pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs));
988 if (erasing_res_graph.valid(pred[v])) {
989 free1.set(w, std::min(free1[v], res_graph.resCap(
990 typename ErasingResGW::OutEdgeIt(dfs))));
992 free1.set(w, res_graph.resCap(
993 typename ErasingResGW::OutEdgeIt(dfs)));
1002 erasing_res_graph.erase(dfs);
1008 typename ErasingResGW::Node n=typename FilterResGW::Node(typename ResGW::Node(t));
1009 // typename ResGW::NodeMap<Num> a(res_graph);
1010 // typename ResGW::Node b;
1012 // typename FilterResGW::NodeMap<Num> a1(filter_res_graph);
1013 // typename FilterResGW::Node b1;
1015 // typename ErasingResGW::NodeMap<Num> a2(erasing_res_graph);
1016 // typename ErasingResGW::Node b2;
1018 Num augment_value=free1[n];
1019 while (erasing_res_graph.valid(pred[n])) {
1020 typename ErasingResGW::OutEdgeIt e=pred[n];
1021 res_graph.augment(e, augment_value);
1022 n=erasing_res_graph.tail(e);
1023 if (res_graph.resCap(e)==0)
1024 erasing_res_graph.erase(e);
1028 } //while (__augment)
1038 #endif //HUGO_MAX_FLOW_H