.
1 #ifndef EDMONDS_KARP_HH
2 #define EDMONDS_KARP_HH
6 #include <bfs_iterator.hh>
10 template<typename Graph, typename T, typename FlowMap, typename CapacityMap>
12 typedef typename Graph::NodeIt NodeIt;
13 typedef typename Graph::EachNodeIt EachNodeIt;
14 typedef typename Graph::SymEdgeIt OldSymEdgeIt;
17 const CapacityMap& capacity;
19 ResGraph(const Graph& _G, FlowMap& _flow,
20 const CapacityMap& _capacity) :
21 G(_G), flow(_flow), capacity(_capacity) { }
26 friend class OutEdgeIt;
29 friend class ResGraph<Graph, T, FlowMap, CapacityMap>;
31 const ResGraph<Graph, T, FlowMap, CapacityMap>* resG;
35 //EdgeIt(const EdgeIt& e) : resG(e.resG), sym(e.sym) { }
37 if (resG->G.aNode(sym)==resG->G.tail(sym)) {
38 return (resG->capacity.get(sym)-resG->flow.get(sym));
40 return (resG->flow.get(sym));
43 bool valid() const { return sym.valid(); }
44 void augment(T a) const {
45 if (resG->G.aNode(sym)==resG->G.tail(sym)) {
46 resG->flow.set(sym, resG->flow.get(sym)+a);
48 resG->flow.set(sym, resG->flow.get(sym)-a);
53 class OutEdgeIt : public EdgeIt {
54 friend class ResGraph<Graph, T, FlowMap, CapacityMap>;
57 //OutEdgeIt(const OutEdgeIt& e) { resG=e.resG; sym=e.sym; }
59 OutEdgeIt(const ResGraph<Graph, T, FlowMap, CapacityMap>& _resG, NodeIt v) {
61 sym=resG->G.template first<OldSymEdgeIt>(v);
62 while( sym.valid() && !(free()>0) ) { ++sym; }
65 OutEdgeIt& operator++() {
67 while( sym.valid() && !(free()>0) ) { ++sym; }
72 void getFirst(OutEdgeIt& e, NodeIt v) const {
73 e=OutEdgeIt(*this, v);
75 void getFirst(EachNodeIt& v) const { G.getFirst(v); }
77 template< typename It >
84 template< typename It >
85 It first(NodeIt v) const {
91 NodeIt tail(EdgeIt e) const { return G.aNode(e.sym); }
92 NodeIt head(EdgeIt e) const { return G.bNode(e.sym); }
94 NodeIt aNode(OutEdgeIt e) const { return G.aNode(e.sym); }
95 NodeIt bNode(OutEdgeIt e) const { return G.bNode(e.sym); }
97 int id(NodeIt v) const { return G.id(v); }
99 template <typename ValueType>
101 typename Graph::NodeMap<ValueType> node_map;
103 NodeMap(const ResGraph<Graph, T, FlowMap, CapacityMap>& _G) : node_map(_G.G) { }
104 NodeMap(const ResGraph<Graph, T, FlowMap, CapacityMap>& _G, ValueType a) : node_map(_G.G, a) { }
105 void set(NodeIt nit, ValueType a) { node_map.set(nit, a); }
106 ValueType get(NodeIt nit) const { return node_map.get(nit); }
111 template <typename Graph, typename T, typename FlowMap, typename CapacityMap>
113 typedef typename Graph::NodeIt NodeIt;
114 typedef typename Graph::EdgeIt EdgeIt;
115 typedef typename Graph::EachEdgeIt EachEdgeIt;
116 typedef typename Graph::OutEdgeIt OutEdgeIt;
117 typedef typename Graph::InEdgeIt InEdgeIt;
122 const CapacityMap& capacity;
123 typedef ResGraph<Graph, T, FlowMap, CapacityMap > AugGraph;
124 typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
125 typedef typename AugGraph::EdgeIt AugEdgeIt;
127 MaxFlow(const Graph& _G, NodeIt _s, NodeIt _t, FlowMap& _flow, const CapacityMap& _capacity) : G(_G), s(_s), t(_t), flow(_flow), capacity(_capacity) { }
129 AugGraph res_graph(G, flow, capacity);
132 typedef typename AugGraph::NodeMap<bool> ReachedMap;
133 BfsIterator2< AugGraph, AugOutEdgeIt, ReachedMap > res_bfs(res_graph);
134 res_bfs.pushAndSetReached(s);
136 typename AugGraph::NodeMap<AugEdgeIt> pred(res_graph);
137 //filled with invalid iterators
139 typename AugGraph::NodeMap<int> free(res_graph);
141 //searching for augmenting path
142 while ( !res_bfs.finished() ) {
143 //std::queue<AugOutEdgeIt> bfs_copy(res_bfs.getBfsQueue());
144 //while (!bfs_copy.empty()) {
145 // AugOutEdgeIt e=bfs_copy.front();
148 // std::cout<<"queue:"<<res_graph.tail(e)<<"->"<<res_graph.head(e)<<" ";
150 // std::cout<<"queue:"<<res_graph.aNode(e)<<"->"<<" ";
153 //std::cout<<std::endl;
154 AugOutEdgeIt e=AugOutEdgeIt(res_bfs);
156 // std::cout<<"actual:"<<res_graph.tail(e)<<"->"<<res_graph.head(e)<<std::endl;
158 // std::cout<<"actual:"<<res_graph.aNode(e)<<"->"<<std::endl;
160 if (e.valid() && res_bfs.isBNodeNewlyReached()) {
161 NodeIt v=res_graph.tail(e);
162 NodeIt w=res_graph.head(e);
163 //std::cout<<v<<"->"<<w<<std::endl;
165 if (pred.get(v).valid()) {
166 free.set(w, std::min(free.get(v), e.free()));
168 free.set(w, e.free());
170 if (res_graph.head(e)==t) { _augment=true; break; }
174 } //end of searching augmenting path
178 T augment_value=free.get(t);
179 //std::cout<<"augmentation: ";
180 while (pred.get(n).valid()) {
181 AugEdgeIt e=pred.get(n);
182 e.augment(augment_value);
183 //std::cout<<"("<<res_graph.tail(e)<< "->"<<res_graph.head(e)<<") ";
186 //std::cout<<std::endl;
188 //std::cout << "actual flow: "<< std::endl;
189 //for(EachEdgeIt e=G.template first<EachEdgeIt>(); e.valid(); ++e) {
190 //std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
192 //std::cout<<std::endl;
197 while (augment()) { }
203 #endif //EDMONDS_KARP_HH