# HG changeset patch # User marci # Date 1083254830 0 # Node ID 229a16b5fd0f576afb2840162e0d2755275472f7 # Parent 2cef25dcde3f9c8e10f86d5f21e9196759078c8e edmonds_karp diff -r 2cef25dcde3f -r 229a16b5fd0f src/work/marci/edmonds_karp.h --- a/src/work/marci/edmonds_karp.h Thu Apr 29 16:04:27 2004 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,956 +0,0 @@ -// -*- c++ -*- -#ifndef HUGO_EDMONDS_KARP_H -#define HUGO_EDMONDS_KARP_H - -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace hugo { - - template - class MaxFlow { - protected: - typedef typename Graph::Node Node; - typedef typename Graph::Edge Edge; - typedef typename Graph::EdgeIt EdgeIt; - typedef typename Graph::OutEdgeIt OutEdgeIt; - typedef typename Graph::InEdgeIt InEdgeIt; - const Graph* g; - Node s; - Node t; - const CapMap* capacity; - FlowMap* flow; - typedef ResGraphWrapper ResGW; - typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt; - typedef typename ResGW::Edge ResGWEdge; - //typedef typename ResGW::template NodeMap ReachedMap; - typedef typename Graph::template NodeMap ReachedMap; - ReachedMap level; - //reached is called level because of compatibility with preflow - public: - - MaxFlow(const Graph& _g, Node _s, Node _t, const CapMap& _capacity, - FlowMap& _flow) : - g(&_g), s(_s), t(_t), capacity(&_capacity), flow(&_flow), level(_g) { } - - bool 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 bfs(res_graph, level); - bfs.pushAndSetReached(s); - - typename ResGW::template NodeMap pred(res_graph); - pred.set(s, INVALID); - - typename ResGW::template NodeMap 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); - } - } - - return _augment; - } - - template - class DistanceMap { - protected: - const MapGraphWrapper* g; - typename MapGraphWrapper::template NodeMap 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) - { 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))head(e))); } - bool operator[](const typename MapGraphWrapper::Edge& e) const { - return (dist[g->tail(e)]head(e)]); - } - }; - - template bool augmentOnBlockingFlow() { - typedef MutableGraph MG; - 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 bfs(res_graph, level); - - bfs.pushAndSetReached(s); - //typename ResGW::NodeMap dist(res_graph); //filled up with 0's - DistanceMap 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 - - MG F; - ConstMap true_map(true); - typedef SubGraphWrapper, - DistanceMap > FilterResGW; - FilterResGW filter_res_graph(res_graph, true_map, dist); - typename ResGW::template NodeMap - 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 original_edge(F); - typename MG::template EdgeMap residual_capacity(F); - - //Making F to the graph containing the edges of the residual graph - //which are in some shortest paths - { - typename FilterResGW::EdgeIt e; - for(filter_res_graph.first(e); filter_res_graph.valid(e); filter_res_graph.next(e)) { - //if (dist.get(res_graph.head(e))==dist.get(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)); - //} - } - } - - bool __augment=true; - - while (__augment) { - __augment=false; - //computing blocking flow with dfs - - DfsIterator< MG, typename MG::template NodeMap > dfs(F); - typename MG::template NodeMap pred(F); - pred.set(sF, INVALID); - //invalid iterators for sources - - typename MG::template NodeMap 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); - } - } - - } - - return _augment; - } - - template bool augmentOnBlockingFlow1() { - 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 bfs(res_graph, level); - bfs.pushAndSetReached(s); - typename ResGW::template NodeMap - 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 - 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 original_edge(F); - typename MG::template EdgeMap 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 > dfs(F); - typename MG::template NodeMap pred(F); - pred.set(sF, INVALID); - //invalid iterators for sources - - typename MG::template NodeMap 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); - } - } - - } - - return _augment; - } - - bool 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 bfs(res_graph, level); - - bfs.pushAndSetReached(s); - DistanceMap 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 true_map(true); - typedef SubGraphWrapper, - DistanceMap > 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 - 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 > 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 > - dfs(erasing_res_graph); - typename ErasingResGW:: - template NodeMap - pred(erasing_res_graph); - pred.set(s, INVALID); - //invalid iterators for sources - - typename ErasingResGW::template NodeMap - 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()) { - - 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 a(res_graph); -// typename ResGW::Node b; -// Num j=a[b]; -// typename FilterResGW::NodeMap a1(filter_res_graph); -// typename FilterResGW::Node b1; -// Num j1=a1[b1]; -// typename ErasingResGW::NodeMap 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) - - return _augment; - } - - void run() { - //int num_of_augmentations=0; - while (augmentOnShortestPath()) { - //while (augmentOnBlockingFlow()) { - //std::cout << ++num_of_augmentations << " "; - //std::cout< void run() { - //int num_of_augmentations=0; - //while (augmentOnShortestPath()) { - while (augmentOnBlockingFlow()) { - //std::cout << ++num_of_augmentations << " "; - //std::cout<first(e, s); g->valid(e); g->next(e)) { - a+=(*flow)[e]; - } - return a; - } - - }; - - -// template -// class MaxMatching { -// public: -// typedef typename Graph::Node Node; -// typedef typename Graph::NodeIt NodeIt; -// typedef typename Graph::Edge Edge; -// typedef typename Graph::EdgeIt EdgeIt; -// typedef typename Graph::OutEdgeIt OutEdgeIt; -// typedef typename Graph::InEdgeIt InEdgeIt; - -// typedef typename Graph::NodeMap SMap; -// typedef typename Graph::NodeMap TMap; -// private: -// const Graph* G; -// SMap* S; -// TMap* T; -// //Node s; -// //Node t; -// FlowMap* flow; -// const CapMap* capacity; -// typedef ResGraphWrapper AugGraph; -// typedef typename AugGraph::OutEdgeIt AugOutEdgeIt; -// typedef typename AugGraph::Edge AugEdge; -// typename Graph::NodeMap used; //0 - -// public: -// MaxMatching(const Graph& _G, SMap& _S, TMap& _T, FlowMap& _flow, const CapMap& _capacity) : -// G(&_G), S(&_S), T(&_T), flow(&_flow), capacity(&_capacity), used(_G) { } -// bool augmentOnShortestPath() { -// AugGraph res_graph(*G, *flow, *capacity); -// bool _augment=false; - -// typedef typename AugGraph::NodeMap ReachedMap; -// BfsIterator< AugGraph, /*AugOutEdgeIt,*/ ReachedMap > bfs(res_graph); -// typename AugGraph::NodeMap pred(res_graph); -// for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { -// if ((S->get(s)) && (used.get(s)<1) ) { -// //Num u=0; -// //for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) -// //u+=flow->get(e); -// //if (u<1) { -// bfs.pushAndSetReached(s); -// pred.set(s, AugEdge(INVALID)); -// //} -// } -// } - -// typename AugGraph::NodeMap free(res_graph); - -// Node n; -// //searching for augmenting path -// while ( !bfs.finished() ) { -// AugOutEdgeIt 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.get(v))) { -// free.set(w, std::min(free.get(v), res_graph.free(e))); -// } else { -// free.set(w, res_graph.free(e)); -// } -// n=res_graph.head(e); -// if (T->get(n) && (used.get(n)<1) ) { -// //Num u=0; -// //for(InEdgeIt f=G->template first(n); G->valid(f); G->next(f)) -// //u+=flow->get(f); -// //if (u<1) { -// _augment=true; -// break; -// //} -// } -// } - -// ++bfs; -// } //end of searching augmenting path - -// if (_augment) { -// //Node n=t; -// used.set(n, 1); //mind2 vegen jav -// Num augment_value=free.get(n); -// while (res_graph.valid(pred.get(n))) { -// AugEdge e=pred.get(n); -// res_graph.augment(e, augment_value); -// n=res_graph.tail(e); -// } -// used.set(n, 1); //mind2 vegen jav -// } - -// return _augment; -// } - -// // template bool augmentOnBlockingFlow() { -// // bool _augment=false; - -// // AugGraph res_graph(*G, *flow, *capacity); - -// // typedef typename AugGraph::NodeMap ReachedMap; -// // BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph); - - - - - -// // //typename AugGraph::NodeMap pred(res_graph); -// // for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { -// // if (S->get(s)) { -// // Num u=0; -// // for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) -// // u+=flow->get(e); -// // if (u<1) { -// // bfs.pushAndSetReached(s); -// // //pred.set(s, AugEdge(INVALID)); -// // } -// // } -// // } - - - - -// // //bfs.pushAndSetReached(s); -// // typename AugGraph::NodeMap dist(res_graph); //filled up with 0's -// // while ( !bfs.finished() ) { -// // AugOutEdgeIt e=bfs; -// // if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) { -// // dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1); -// // } - -// // ++bfs; -// // } //computing distances from s in the residual graph - -// // MutableGraph F; -// // typename AugGraph::NodeMap -// // res_graph_to_F(res_graph); -// // for(typename AugGraph::NodeIt n=res_graph.template first(); res_graph.valid(n); res_graph.next(n)) { -// // res_graph_to_F.set(n, F.addNode()); -// // } - -// // typename MutableGraph::Node sF=res_graph_to_F.get(s); -// // typename MutableGraph::Node tF=res_graph_to_F.get(t); - -// // typename MutableGraph::EdgeMap original_edge(F); -// // typename MutableGraph::EdgeMap residual_capacity(F); - -// // //Making F to the graph containing the edges of the residual graph -// // //which are in some shortest paths -// // for(typename AugGraph::EdgeIt e=res_graph.template first(); res_graph.valid(e); res_graph.next(e)) { -// // if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) { -// // typename MutableGraph::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e))); -// // original_edge.update(); -// // original_edge.set(f, e); -// // residual_capacity.update(); -// // residual_capacity.set(f, res_graph.free(e)); -// // } -// // } - -// // bool __augment=true; - -// // while (__augment) { -// // __augment=false; -// // //computing blocking flow with dfs -// // typedef typename MutableGraph::NodeMap BlockingReachedMap; -// // DfsIterator4< MutableGraph, typename MutableGraph::OutEdgeIt, BlockingReachedMap > dfs(F); -// // typename MutableGraph::NodeMap pred(F); -// // pred.set(sF, typename MutableGraph::Edge(INVALID)); -// // //invalid iterators for sources - -// // typename MutableGraph::NodeMap free(F); - -// // dfs.pushAndSetReached(sF); -// // while (!dfs.finished()) { -// // ++dfs; -// // if (F.valid(typename MutableGraph::OutEdgeIt(dfs))) { -// // if (dfs.isBNodeNewlyReached()) { -// // typename MutableGraph::Node v=F.aNode(dfs); -// // typename MutableGraph::Node w=F.bNode(dfs); -// // pred.set(w, dfs); -// // if (F.valid(pred.get(v))) { -// // free.set(w, std::min(free.get(v), residual_capacity.get(dfs))); -// // } else { -// // free.set(w, residual_capacity.get(dfs)); -// // } -// // if (w==tF) { -// // __augment=true; -// // _augment=true; -// // break; -// // } - -// // } else { -// // F.erase(typename MutableGraph::OutEdgeIt(dfs)); -// // } -// // } -// // } - -// // if (__augment) { -// // typename MutableGraph::Node n=tF; -// // Num augment_value=free.get(tF); -// // while (F.valid(pred.get(n))) { -// // typename MutableGraph::Edge e=pred.get(n); -// // res_graph.augment(original_edge.get(e), augment_value); -// // n=F.tail(e); -// // if (residual_capacity.get(e)==augment_value) -// // F.erase(e); -// // else -// // residual_capacity.set(e, residual_capacity.get(e)-augment_value); -// // } -// // } - -// // } - -// // return _augment; -// // } -// bool augmentOnBlockingFlow2() { -// bool _augment=false; - -// //typedef ErasingResGraphWrapper EAugGraph; -// typedef FilterGraphWrapper< ErasingResGraphWrapper > EAugGraph; -// typedef typename EAugGraph::OutEdgeIt EAugOutEdgeIt; -// typedef typename EAugGraph::Edge EAugEdge; - -// EAugGraph res_graph(*G, *flow, *capacity); - -// //typedef typename EAugGraph::NodeMap ReachedMap; -// BfsIterator< -// ErasingResGraphWrapper, -// /*typename ErasingResGraphWrapper::OutEdgeIt,*/ -// ErasingResGraphWrapper::NodeMap > bfs(res_graph); - - -// //typename AugGraph::NodeMap pred(res_graph); -// for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { -// if (S->get(s)) { -// Num u=0; -// for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) -// u+=flow->get(e); -// if (u<1) { -// bfs.pushAndSetReached(s); -// //pred.set(s, AugEdge(INVALID)); -// } -// } -// } - - -// //bfs.pushAndSetReached(s); - -// typename ErasingResGraphWrapper:: -// NodeMap& dist=res_graph.dist; - -// while ( !bfs.finished() ) { -// typename ErasingResGraphWrapper::OutEdgeIt e=bfs; -// if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) { -// dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1); -// } -// ++bfs; -// } //computing distances from s in the residual graph - -// bool __augment=true; - -// while (__augment) { - -// __augment=false; -// //computing blocking flow with dfs -// typedef typename EAugGraph::NodeMap BlockingReachedMap; -// DfsIterator< EAugGraph/*, EAugOutEdgeIt*/, BlockingReachedMap > -// dfs(res_graph); -// typename EAugGraph::NodeMap pred(res_graph, INVALID); -// //pred.set(s, EAugEdge(INVALID)); -// //invalid iterators for sources - -// typename EAugGraph::NodeMap free(res_graph); - - -// //typename AugGraph::NodeMap pred(res_graph); -// for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { -// if (S->get(s)) { -// Num u=0; -// for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) -// u+=flow->get(e); -// if (u<1) { -// dfs.pushAndSetReached(s); -// //pred.set(s, AugEdge(INVALID)); -// } -// } -// } - - - -// //dfs.pushAndSetReached(s); -// typename EAugGraph::Node n; -// while (!dfs.finished()) { -// ++dfs; -// if (res_graph.valid(EAugOutEdgeIt(dfs))) { -// if (dfs.isBNodeNewlyReached()) { - -// typename EAugGraph::Node v=res_graph.aNode(dfs); -// typename EAugGraph::Node w=res_graph.bNode(dfs); - -// pred.set(w, EAugOutEdgeIt(dfs)); -// if (res_graph.valid(pred.get(v))) { -// free.set(w, std::min(free.get(v), res_graph.free(dfs))); -// } else { -// free.set(w, res_graph.free(dfs)); -// } - -// n=w; -// if (T->get(w)) { -// Num u=0; -// for(InEdgeIt f=G->template first(n); G->valid(f); G->next(f)) -// u+=flow->get(f); -// if (u<1) { -// __augment=true; -// _augment=true; -// break; -// } -// } -// } else { -// res_graph.erase(dfs); -// } -// } - -// } - -// if (__augment) { -// // typename EAugGraph::Node n=t; -// Num augment_value=free.get(n); -// while (res_graph.valid(pred.get(n))) { -// EAugEdge e=pred.get(n); -// res_graph.augment(e, augment_value); -// n=res_graph.tail(e); -// if (res_graph.free(e)==0) -// res_graph.erase(e); -// } -// } - -// } - -// return _augment; -// } -// void run() { -// //int num_of_augmentations=0; -// while (augmentOnShortestPath()) { -// //while (augmentOnBlockingFlow()) { -// //std::cout << ++num_of_augmentations << " "; -// //std::cout< void run() { -// // //int num_of_augmentations=0; -// // //while (augmentOnShortestPath()) { -// // while (augmentOnBlockingFlow()) { -// // //std::cout << ++num_of_augmentations << " "; -// // //std::cout</*getF*/first(e); G->valid(e); G->next(e)) { -// a+=flow->get(e); -// } -// return a; -// } -// }; - - - - - - -// // template -// // class MaxFlow2 { -// // public: -// // typedef typename Graph::Node Node; -// // typedef typename Graph::Edge Edge; -// // typedef typename Graph::EdgeIt EdgeIt; -// // typedef typename Graph::OutEdgeIt OutEdgeIt; -// // typedef typename Graph::InEdgeIt InEdgeIt; -// // private: -// // const Graph& G; -// // std::list& S; -// // std::list& T; -// // FlowMap& flow; -// // const CapMap& capacity; -// // typedef ResGraphWrapper AugGraph; -// // typedef typename AugGraph::OutEdgeIt AugOutEdgeIt; -// // typedef typename AugGraph::Edge AugEdge; -// // typename Graph::NodeMap SMap; -// // typename Graph::NodeMap TMap; -// // public: -// // MaxFlow2(const Graph& _G, std::list& _S, std::list& _T, FlowMap& _flow, const CapMap& _capacity) : G(_G), S(_S), T(_T), flow(_flow), capacity(_capacity), SMap(_G), TMap(_G) { -// // for(typename std::list::const_iterator i=S.begin(); -// // i!=S.end(); ++i) { -// // SMap.set(*i, true); -// // } -// // for (typename std::list::const_iterator i=T.begin(); -// // i!=T.end(); ++i) { -// // TMap.set(*i, true); -// // } -// // } -// // bool augment() { -// // AugGraph res_graph(G, flow, capacity); -// // bool _augment=false; -// // Node reached_t_node; - -// // typedef typename AugGraph::NodeMap ReachedMap; -// // BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph); -// // for(typename std::list::const_iterator i=S.begin(); -// // i!=S.end(); ++i) { -// // bfs.pushAndSetReached(*i); -// // } -// // //bfs.pushAndSetReached(s); - -// // typename AugGraph::NodeMap pred(res_graph); -// // //filled up with invalid iterators - -// // typename AugGraph::NodeMap free(res_graph); - -// // //searching for augmenting path -// // while ( !bfs.finished() ) { -// // AugOutEdgeIt e=/*AugOutEdgeIt*/(bfs); -// // if (e.valid() && bfs.isBNodeNewlyReached()) { -// // Node v=res_graph.tail(e); -// // Node w=res_graph.head(e); -// // pred.set(w, e); -// // if (pred.get(v).valid()) { -// // free.set(w, std::min(free.get(v), e.free())); -// // } else { -// // free.set(w, e.free()); -// // } -// // if (TMap.get(res_graph.head(e))) { -// // _augment=true; -// // reached_t_node=res_graph.head(e); -// // break; -// // } -// // } - -// // ++bfs; -// // } //end of searching augmenting path - -// // if (_augment) { -// // Node n=reached_t_node; -// // Num augment_value=free.get(reached_t_node); -// // while (pred.get(n).valid()) { -// // AugEdge e=pred.get(n); -// // e.augment(augment_value); -// // n=res_graph.tail(e); -// // } -// // } - -// // return _augment; -// // } -// // void run() { -// // while (augment()) { } -// // } -// // Num flowValue() { -// // Num a=0; -// // for(typename std::list::const_iterator i=S.begin(); -// // i!=S.end(); ++i) { -// // for(OutEdgeIt e=G.template first(*i); e.valid(); ++e) { -// // a+=flow.get(e); -// // } -// // for(InEdgeIt e=G.template first(*i); e.valid(); ++e) { -// // a-=flow.get(e); -// // } -// // } -// // return a; -// // } -// // }; - - -} // namespace hugo - -#endif //HUGO_EDMONDS_KARP_H diff -r 2cef25dcde3f -r 229a16b5fd0f src/work/marci/oldies/edmonds_karp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/marci/oldies/edmonds_karp.h Thu Apr 29 16:07:10 2004 +0000 @@ -0,0 +1,956 @@ +// -*- c++ -*- +#ifndef HUGO_EDMONDS_KARP_H +#define HUGO_EDMONDS_KARP_H + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace hugo { + + template + class MaxFlow { + protected: + typedef typename Graph::Node Node; + typedef typename Graph::Edge Edge; + typedef typename Graph::EdgeIt EdgeIt; + typedef typename Graph::OutEdgeIt OutEdgeIt; + typedef typename Graph::InEdgeIt InEdgeIt; + const Graph* g; + Node s; + Node t; + const CapMap* capacity; + FlowMap* flow; + typedef ResGraphWrapper ResGW; + typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt; + typedef typename ResGW::Edge ResGWEdge; + //typedef typename ResGW::template NodeMap ReachedMap; + typedef typename Graph::template NodeMap ReachedMap; + ReachedMap level; + //reached is called level because of compatibility with preflow + public: + + MaxFlow(const Graph& _g, Node _s, Node _t, const CapMap& _capacity, + FlowMap& _flow) : + g(&_g), s(_s), t(_t), capacity(&_capacity), flow(&_flow), level(_g) { } + + bool 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 bfs(res_graph, level); + bfs.pushAndSetReached(s); + + typename ResGW::template NodeMap pred(res_graph); + pred.set(s, INVALID); + + typename ResGW::template NodeMap 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); + } + } + + return _augment; + } + + template + class DistanceMap { + protected: + const MapGraphWrapper* g; + typename MapGraphWrapper::template NodeMap 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) + { 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))head(e))); } + bool operator[](const typename MapGraphWrapper::Edge& e) const { + return (dist[g->tail(e)]head(e)]); + } + }; + + template bool augmentOnBlockingFlow() { + typedef MutableGraph MG; + 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 bfs(res_graph, level); + + bfs.pushAndSetReached(s); + //typename ResGW::NodeMap dist(res_graph); //filled up with 0's + DistanceMap 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 + + MG F; + ConstMap true_map(true); + typedef SubGraphWrapper, + DistanceMap > FilterResGW; + FilterResGW filter_res_graph(res_graph, true_map, dist); + typename ResGW::template NodeMap + 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 original_edge(F); + typename MG::template EdgeMap residual_capacity(F); + + //Making F to the graph containing the edges of the residual graph + //which are in some shortest paths + { + typename FilterResGW::EdgeIt e; + for(filter_res_graph.first(e); filter_res_graph.valid(e); filter_res_graph.next(e)) { + //if (dist.get(res_graph.head(e))==dist.get(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)); + //} + } + } + + bool __augment=true; + + while (__augment) { + __augment=false; + //computing blocking flow with dfs + + DfsIterator< MG, typename MG::template NodeMap > dfs(F); + typename MG::template NodeMap pred(F); + pred.set(sF, INVALID); + //invalid iterators for sources + + typename MG::template NodeMap 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); + } + } + + } + + return _augment; + } + + template bool augmentOnBlockingFlow1() { + 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 bfs(res_graph, level); + bfs.pushAndSetReached(s); + typename ResGW::template NodeMap + 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 + 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 original_edge(F); + typename MG::template EdgeMap 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 > dfs(F); + typename MG::template NodeMap pred(F); + pred.set(sF, INVALID); + //invalid iterators for sources + + typename MG::template NodeMap 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); + } + } + + } + + return _augment; + } + + bool 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 bfs(res_graph, level); + + bfs.pushAndSetReached(s); + DistanceMap 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 true_map(true); + typedef SubGraphWrapper, + DistanceMap > 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 + 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 > 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 > + dfs(erasing_res_graph); + typename ErasingResGW:: + template NodeMap + pred(erasing_res_graph); + pred.set(s, INVALID); + //invalid iterators for sources + + typename ErasingResGW::template NodeMap + 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()) { + + 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 a(res_graph); +// typename ResGW::Node b; +// Num j=a[b]; +// typename FilterResGW::NodeMap a1(filter_res_graph); +// typename FilterResGW::Node b1; +// Num j1=a1[b1]; +// typename ErasingResGW::NodeMap 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) + + return _augment; + } + + void run() { + //int num_of_augmentations=0; + while (augmentOnShortestPath()) { + //while (augmentOnBlockingFlow()) { + //std::cout << ++num_of_augmentations << " "; + //std::cout< void run() { + //int num_of_augmentations=0; + //while (augmentOnShortestPath()) { + while (augmentOnBlockingFlow()) { + //std::cout << ++num_of_augmentations << " "; + //std::cout<first(e, s); g->valid(e); g->next(e)) { + a+=(*flow)[e]; + } + return a; + } + + }; + + +// template +// class MaxMatching { +// public: +// typedef typename Graph::Node Node; +// typedef typename Graph::NodeIt NodeIt; +// typedef typename Graph::Edge Edge; +// typedef typename Graph::EdgeIt EdgeIt; +// typedef typename Graph::OutEdgeIt OutEdgeIt; +// typedef typename Graph::InEdgeIt InEdgeIt; + +// typedef typename Graph::NodeMap SMap; +// typedef typename Graph::NodeMap TMap; +// private: +// const Graph* G; +// SMap* S; +// TMap* T; +// //Node s; +// //Node t; +// FlowMap* flow; +// const CapMap* capacity; +// typedef ResGraphWrapper AugGraph; +// typedef typename AugGraph::OutEdgeIt AugOutEdgeIt; +// typedef typename AugGraph::Edge AugEdge; +// typename Graph::NodeMap used; //0 + +// public: +// MaxMatching(const Graph& _G, SMap& _S, TMap& _T, FlowMap& _flow, const CapMap& _capacity) : +// G(&_G), S(&_S), T(&_T), flow(&_flow), capacity(&_capacity), used(_G) { } +// bool augmentOnShortestPath() { +// AugGraph res_graph(*G, *flow, *capacity); +// bool _augment=false; + +// typedef typename AugGraph::NodeMap ReachedMap; +// BfsIterator< AugGraph, /*AugOutEdgeIt,*/ ReachedMap > bfs(res_graph); +// typename AugGraph::NodeMap pred(res_graph); +// for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { +// if ((S->get(s)) && (used.get(s)<1) ) { +// //Num u=0; +// //for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) +// //u+=flow->get(e); +// //if (u<1) { +// bfs.pushAndSetReached(s); +// pred.set(s, AugEdge(INVALID)); +// //} +// } +// } + +// typename AugGraph::NodeMap free(res_graph); + +// Node n; +// //searching for augmenting path +// while ( !bfs.finished() ) { +// AugOutEdgeIt 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.get(v))) { +// free.set(w, std::min(free.get(v), res_graph.free(e))); +// } else { +// free.set(w, res_graph.free(e)); +// } +// n=res_graph.head(e); +// if (T->get(n) && (used.get(n)<1) ) { +// //Num u=0; +// //for(InEdgeIt f=G->template first(n); G->valid(f); G->next(f)) +// //u+=flow->get(f); +// //if (u<1) { +// _augment=true; +// break; +// //} +// } +// } + +// ++bfs; +// } //end of searching augmenting path + +// if (_augment) { +// //Node n=t; +// used.set(n, 1); //mind2 vegen jav +// Num augment_value=free.get(n); +// while (res_graph.valid(pred.get(n))) { +// AugEdge e=pred.get(n); +// res_graph.augment(e, augment_value); +// n=res_graph.tail(e); +// } +// used.set(n, 1); //mind2 vegen jav +// } + +// return _augment; +// } + +// // template bool augmentOnBlockingFlow() { +// // bool _augment=false; + +// // AugGraph res_graph(*G, *flow, *capacity); + +// // typedef typename AugGraph::NodeMap ReachedMap; +// // BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph); + + + + + +// // //typename AugGraph::NodeMap pred(res_graph); +// // for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { +// // if (S->get(s)) { +// // Num u=0; +// // for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) +// // u+=flow->get(e); +// // if (u<1) { +// // bfs.pushAndSetReached(s); +// // //pred.set(s, AugEdge(INVALID)); +// // } +// // } +// // } + + + + +// // //bfs.pushAndSetReached(s); +// // typename AugGraph::NodeMap dist(res_graph); //filled up with 0's +// // while ( !bfs.finished() ) { +// // AugOutEdgeIt e=bfs; +// // if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) { +// // dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1); +// // } + +// // ++bfs; +// // } //computing distances from s in the residual graph + +// // MutableGraph F; +// // typename AugGraph::NodeMap +// // res_graph_to_F(res_graph); +// // for(typename AugGraph::NodeIt n=res_graph.template first(); res_graph.valid(n); res_graph.next(n)) { +// // res_graph_to_F.set(n, F.addNode()); +// // } + +// // typename MutableGraph::Node sF=res_graph_to_F.get(s); +// // typename MutableGraph::Node tF=res_graph_to_F.get(t); + +// // typename MutableGraph::EdgeMap original_edge(F); +// // typename MutableGraph::EdgeMap residual_capacity(F); + +// // //Making F to the graph containing the edges of the residual graph +// // //which are in some shortest paths +// // for(typename AugGraph::EdgeIt e=res_graph.template first(); res_graph.valid(e); res_graph.next(e)) { +// // if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) { +// // typename MutableGraph::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e))); +// // original_edge.update(); +// // original_edge.set(f, e); +// // residual_capacity.update(); +// // residual_capacity.set(f, res_graph.free(e)); +// // } +// // } + +// // bool __augment=true; + +// // while (__augment) { +// // __augment=false; +// // //computing blocking flow with dfs +// // typedef typename MutableGraph::NodeMap BlockingReachedMap; +// // DfsIterator4< MutableGraph, typename MutableGraph::OutEdgeIt, BlockingReachedMap > dfs(F); +// // typename MutableGraph::NodeMap pred(F); +// // pred.set(sF, typename MutableGraph::Edge(INVALID)); +// // //invalid iterators for sources + +// // typename MutableGraph::NodeMap free(F); + +// // dfs.pushAndSetReached(sF); +// // while (!dfs.finished()) { +// // ++dfs; +// // if (F.valid(typename MutableGraph::OutEdgeIt(dfs))) { +// // if (dfs.isBNodeNewlyReached()) { +// // typename MutableGraph::Node v=F.aNode(dfs); +// // typename MutableGraph::Node w=F.bNode(dfs); +// // pred.set(w, dfs); +// // if (F.valid(pred.get(v))) { +// // free.set(w, std::min(free.get(v), residual_capacity.get(dfs))); +// // } else { +// // free.set(w, residual_capacity.get(dfs)); +// // } +// // if (w==tF) { +// // __augment=true; +// // _augment=true; +// // break; +// // } + +// // } else { +// // F.erase(typename MutableGraph::OutEdgeIt(dfs)); +// // } +// // } +// // } + +// // if (__augment) { +// // typename MutableGraph::Node n=tF; +// // Num augment_value=free.get(tF); +// // while (F.valid(pred.get(n))) { +// // typename MutableGraph::Edge e=pred.get(n); +// // res_graph.augment(original_edge.get(e), augment_value); +// // n=F.tail(e); +// // if (residual_capacity.get(e)==augment_value) +// // F.erase(e); +// // else +// // residual_capacity.set(e, residual_capacity.get(e)-augment_value); +// // } +// // } + +// // } + +// // return _augment; +// // } +// bool augmentOnBlockingFlow2() { +// bool _augment=false; + +// //typedef ErasingResGraphWrapper EAugGraph; +// typedef FilterGraphWrapper< ErasingResGraphWrapper > EAugGraph; +// typedef typename EAugGraph::OutEdgeIt EAugOutEdgeIt; +// typedef typename EAugGraph::Edge EAugEdge; + +// EAugGraph res_graph(*G, *flow, *capacity); + +// //typedef typename EAugGraph::NodeMap ReachedMap; +// BfsIterator< +// ErasingResGraphWrapper, +// /*typename ErasingResGraphWrapper::OutEdgeIt,*/ +// ErasingResGraphWrapper::NodeMap > bfs(res_graph); + + +// //typename AugGraph::NodeMap pred(res_graph); +// for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { +// if (S->get(s)) { +// Num u=0; +// for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) +// u+=flow->get(e); +// if (u<1) { +// bfs.pushAndSetReached(s); +// //pred.set(s, AugEdge(INVALID)); +// } +// } +// } + + +// //bfs.pushAndSetReached(s); + +// typename ErasingResGraphWrapper:: +// NodeMap& dist=res_graph.dist; + +// while ( !bfs.finished() ) { +// typename ErasingResGraphWrapper::OutEdgeIt e=bfs; +// if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) { +// dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1); +// } +// ++bfs; +// } //computing distances from s in the residual graph + +// bool __augment=true; + +// while (__augment) { + +// __augment=false; +// //computing blocking flow with dfs +// typedef typename EAugGraph::NodeMap BlockingReachedMap; +// DfsIterator< EAugGraph/*, EAugOutEdgeIt*/, BlockingReachedMap > +// dfs(res_graph); +// typename EAugGraph::NodeMap pred(res_graph, INVALID); +// //pred.set(s, EAugEdge(INVALID)); +// //invalid iterators for sources + +// typename EAugGraph::NodeMap free(res_graph); + + +// //typename AugGraph::NodeMap pred(res_graph); +// for(NodeIt s=G->template first(); G->valid(s); G->next(s)) { +// if (S->get(s)) { +// Num u=0; +// for(OutEdgeIt e=G->template first(s); G->valid(e); G->next(e)) +// u+=flow->get(e); +// if (u<1) { +// dfs.pushAndSetReached(s); +// //pred.set(s, AugEdge(INVALID)); +// } +// } +// } + + + +// //dfs.pushAndSetReached(s); +// typename EAugGraph::Node n; +// while (!dfs.finished()) { +// ++dfs; +// if (res_graph.valid(EAugOutEdgeIt(dfs))) { +// if (dfs.isBNodeNewlyReached()) { + +// typename EAugGraph::Node v=res_graph.aNode(dfs); +// typename EAugGraph::Node w=res_graph.bNode(dfs); + +// pred.set(w, EAugOutEdgeIt(dfs)); +// if (res_graph.valid(pred.get(v))) { +// free.set(w, std::min(free.get(v), res_graph.free(dfs))); +// } else { +// free.set(w, res_graph.free(dfs)); +// } + +// n=w; +// if (T->get(w)) { +// Num u=0; +// for(InEdgeIt f=G->template first(n); G->valid(f); G->next(f)) +// u+=flow->get(f); +// if (u<1) { +// __augment=true; +// _augment=true; +// break; +// } +// } +// } else { +// res_graph.erase(dfs); +// } +// } + +// } + +// if (__augment) { +// // typename EAugGraph::Node n=t; +// Num augment_value=free.get(n); +// while (res_graph.valid(pred.get(n))) { +// EAugEdge e=pred.get(n); +// res_graph.augment(e, augment_value); +// n=res_graph.tail(e); +// if (res_graph.free(e)==0) +// res_graph.erase(e); +// } +// } + +// } + +// return _augment; +// } +// void run() { +// //int num_of_augmentations=0; +// while (augmentOnShortestPath()) { +// //while (augmentOnBlockingFlow()) { +// //std::cout << ++num_of_augmentations << " "; +// //std::cout< void run() { +// // //int num_of_augmentations=0; +// // //while (augmentOnShortestPath()) { +// // while (augmentOnBlockingFlow()) { +// // //std::cout << ++num_of_augmentations << " "; +// // //std::cout</*getF*/first(e); G->valid(e); G->next(e)) { +// a+=flow->get(e); +// } +// return a; +// } +// }; + + + + + + +// // template +// // class MaxFlow2 { +// // public: +// // typedef typename Graph::Node Node; +// // typedef typename Graph::Edge Edge; +// // typedef typename Graph::EdgeIt EdgeIt; +// // typedef typename Graph::OutEdgeIt OutEdgeIt; +// // typedef typename Graph::InEdgeIt InEdgeIt; +// // private: +// // const Graph& G; +// // std::list& S; +// // std::list& T; +// // FlowMap& flow; +// // const CapMap& capacity; +// // typedef ResGraphWrapper AugGraph; +// // typedef typename AugGraph::OutEdgeIt AugOutEdgeIt; +// // typedef typename AugGraph::Edge AugEdge; +// // typename Graph::NodeMap SMap; +// // typename Graph::NodeMap TMap; +// // public: +// // MaxFlow2(const Graph& _G, std::list& _S, std::list& _T, FlowMap& _flow, const CapMap& _capacity) : G(_G), S(_S), T(_T), flow(_flow), capacity(_capacity), SMap(_G), TMap(_G) { +// // for(typename std::list::const_iterator i=S.begin(); +// // i!=S.end(); ++i) { +// // SMap.set(*i, true); +// // } +// // for (typename std::list::const_iterator i=T.begin(); +// // i!=T.end(); ++i) { +// // TMap.set(*i, true); +// // } +// // } +// // bool augment() { +// // AugGraph res_graph(G, flow, capacity); +// // bool _augment=false; +// // Node reached_t_node; + +// // typedef typename AugGraph::NodeMap ReachedMap; +// // BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph); +// // for(typename std::list::const_iterator i=S.begin(); +// // i!=S.end(); ++i) { +// // bfs.pushAndSetReached(*i); +// // } +// // //bfs.pushAndSetReached(s); + +// // typename AugGraph::NodeMap pred(res_graph); +// // //filled up with invalid iterators + +// // typename AugGraph::NodeMap free(res_graph); + +// // //searching for augmenting path +// // while ( !bfs.finished() ) { +// // AugOutEdgeIt e=/*AugOutEdgeIt*/(bfs); +// // if (e.valid() && bfs.isBNodeNewlyReached()) { +// // Node v=res_graph.tail(e); +// // Node w=res_graph.head(e); +// // pred.set(w, e); +// // if (pred.get(v).valid()) { +// // free.set(w, std::min(free.get(v), e.free())); +// // } else { +// // free.set(w, e.free()); +// // } +// // if (TMap.get(res_graph.head(e))) { +// // _augment=true; +// // reached_t_node=res_graph.head(e); +// // break; +// // } +// // } + +// // ++bfs; +// // } //end of searching augmenting path + +// // if (_augment) { +// // Node n=reached_t_node; +// // Num augment_value=free.get(reached_t_node); +// // while (pred.get(n).valid()) { +// // AugEdge e=pred.get(n); +// // e.augment(augment_value); +// // n=res_graph.tail(e); +// // } +// // } + +// // return _augment; +// // } +// // void run() { +// // while (augment()) { } +// // } +// // Num flowValue() { +// // Num a=0; +// // for(typename std::list::const_iterator i=S.begin(); +// // i!=S.end(); ++i) { +// // for(OutEdgeIt e=G.template first(*i); e.valid(); ++e) { +// // a+=flow.get(e); +// // } +// // for(InEdgeIt e=G.template first(*i); e.valid(); ++e) { +// // a-=flow.get(e); +// // } +// // } +// // return a; +// // } +// // }; + + +} // namespace hugo + +#endif //HUGO_EDMONDS_KARP_H