edmonds_karp_max_flow.hpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. //=======================================================================
  2. // Copyright 2000 University of Notre Dame.
  3. // Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. #ifndef EDMONDS_KARP_MAX_FLOW_HPP
  10. #define EDMONDS_KARP_MAX_FLOW_HPP
  11. #include <boost/config.hpp>
  12. #include <vector>
  13. #include <algorithm> // for std::min and std::max
  14. #include <boost/config.hpp>
  15. #include <boost/pending/queue.hpp>
  16. #include <boost/property_map/property_map.hpp>
  17. #include <boost/graph/graph_traits.hpp>
  18. #include <boost/graph/properties.hpp>
  19. #include <boost/graph/filtered_graph.hpp>
  20. #include <boost/graph/breadth_first_search.hpp>
  21. namespace boost {
  22. // The "labeling" algorithm from "Network Flows" by Ahuja, Magnanti,
  23. // Orlin. I think this is the same as or very similar to the original
  24. // Edmonds-Karp algorithm. This solves the maximum flow problem.
  25. namespace detail {
  26. template <class Graph, class ResCapMap>
  27. filtered_graph<Graph, is_residual_edge<ResCapMap> >
  28. residual_graph(Graph& g, ResCapMap residual_capacity) {
  29. return filtered_graph<Graph, is_residual_edge<ResCapMap> >
  30. (g, is_residual_edge<ResCapMap>(residual_capacity));
  31. }
  32. template <class Graph, class PredEdgeMap, class ResCapMap,
  33. class RevEdgeMap>
  34. inline void
  35. augment(Graph& g,
  36. typename graph_traits<Graph>::vertex_descriptor src,
  37. typename graph_traits<Graph>::vertex_descriptor sink,
  38. PredEdgeMap p,
  39. ResCapMap residual_capacity,
  40. RevEdgeMap reverse_edge)
  41. {
  42. typename graph_traits<Graph>::edge_descriptor e;
  43. typename graph_traits<Graph>::vertex_descriptor u;
  44. typedef typename property_traits<ResCapMap>::value_type FlowValue;
  45. // find minimum residual capacity along the augmenting path
  46. FlowValue delta = (std::numeric_limits<FlowValue>::max)();
  47. e = get(p, sink);
  48. do {
  49. BOOST_USING_STD_MIN();
  50. delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, get(residual_capacity, e));
  51. u = source(e, g);
  52. e = get(p, u);
  53. } while (u != src);
  54. // push delta units of flow along the augmenting path
  55. e = get(p, sink);
  56. do {
  57. put(residual_capacity, e, get(residual_capacity, e) - delta);
  58. put(residual_capacity, get(reverse_edge, e), get(residual_capacity, get(reverse_edge, e)) + delta);
  59. u = source(e, g);
  60. e = get(p, u);
  61. } while (u != src);
  62. }
  63. } // namespace detail
  64. template <class Graph,
  65. class CapacityEdgeMap, class ResidualCapacityEdgeMap,
  66. class ReverseEdgeMap, class ColorMap, class PredEdgeMap>
  67. typename property_traits<CapacityEdgeMap>::value_type
  68. edmonds_karp_max_flow
  69. (Graph& g,
  70. typename graph_traits<Graph>::vertex_descriptor src,
  71. typename graph_traits<Graph>::vertex_descriptor sink,
  72. CapacityEdgeMap cap,
  73. ResidualCapacityEdgeMap res,
  74. ReverseEdgeMap rev,
  75. ColorMap color,
  76. PredEdgeMap pred)
  77. {
  78. typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
  79. typedef typename property_traits<ColorMap>::value_type ColorValue;
  80. typedef color_traits<ColorValue> Color;
  81. typename graph_traits<Graph>::vertex_iterator u_iter, u_end;
  82. typename graph_traits<Graph>::out_edge_iterator ei, e_end;
  83. for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
  84. for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
  85. put(res, *ei, get(cap, *ei));
  86. put(color, sink, Color::gray());
  87. while (get(color, sink) != Color::white()) {
  88. boost::queue<vertex_t> Q;
  89. breadth_first_search
  90. (detail::residual_graph(g, res), src, Q,
  91. make_bfs_visitor(record_edge_predecessors(pred, on_tree_edge())),
  92. color);
  93. if (get(color, sink) != Color::white())
  94. detail::augment(g, src, sink, pred, res, rev);
  95. } // while
  96. typename property_traits<CapacityEdgeMap>::value_type flow = 0;
  97. for (boost::tie(ei, e_end) = out_edges(src, g); ei != e_end; ++ei)
  98. flow += (get(cap, *ei) - get(res, *ei));
  99. return flow;
  100. } // edmonds_karp_max_flow()
  101. namespace detail {
  102. //-------------------------------------------------------------------------
  103. // Handle default for color property map
  104. // use of class here is a VC++ workaround
  105. template <class ColorMap>
  106. struct edmonds_karp_dispatch2 {
  107. template <class Graph, class PredMap, class P, class T, class R>
  108. static typename edge_capacity_value<Graph, P, T, R>::type
  109. apply
  110. (Graph& g,
  111. typename graph_traits<Graph>::vertex_descriptor src,
  112. typename graph_traits<Graph>::vertex_descriptor sink,
  113. PredMap pred,
  114. const bgl_named_params<P, T, R>& params,
  115. ColorMap color)
  116. {
  117. return edmonds_karp_max_flow
  118. (g, src, sink,
  119. choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
  120. choose_pmap(get_param(params, edge_residual_capacity),
  121. g, edge_residual_capacity),
  122. choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
  123. color, pred);
  124. }
  125. };
  126. template<>
  127. struct edmonds_karp_dispatch2<param_not_found> {
  128. template <class Graph, class PredMap, class P, class T, class R>
  129. static typename edge_capacity_value<Graph, P, T, R>::type
  130. apply
  131. (Graph& g,
  132. typename graph_traits<Graph>::vertex_descriptor src,
  133. typename graph_traits<Graph>::vertex_descriptor sink,
  134. PredMap pred,
  135. const bgl_named_params<P, T, R>& params,
  136. param_not_found)
  137. {
  138. typedef typename graph_traits<Graph>::vertices_size_type size_type;
  139. size_type n = is_default_param(get_param(params, vertex_color)) ?
  140. num_vertices(g) : 1;
  141. std::vector<default_color_type> color_vec(n);
  142. return edmonds_karp_max_flow
  143. (g, src, sink,
  144. choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
  145. choose_pmap(get_param(params, edge_residual_capacity),
  146. g, edge_residual_capacity),
  147. choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
  148. make_iterator_property_map(color_vec.begin(), choose_const_pmap
  149. (get_param(params, vertex_index),
  150. g, vertex_index), color_vec[0]),
  151. pred);
  152. }
  153. };
  154. //-------------------------------------------------------------------------
  155. // Handle default for predecessor property map
  156. // use of class here is a VC++ workaround
  157. template <class PredMap>
  158. struct edmonds_karp_dispatch1 {
  159. template <class Graph, class P, class T, class R>
  160. static typename edge_capacity_value<Graph, P, T, R>::type
  161. apply(Graph& g,
  162. typename graph_traits<Graph>::vertex_descriptor src,
  163. typename graph_traits<Graph>::vertex_descriptor sink,
  164. const bgl_named_params<P, T, R>& params,
  165. PredMap pred)
  166. {
  167. typedef typename get_param_type< vertex_color_t, bgl_named_params<P,T,R> >::type C;
  168. return edmonds_karp_dispatch2<C>::apply
  169. (g, src, sink, pred, params, get_param(params, vertex_color));
  170. }
  171. };
  172. template<>
  173. struct edmonds_karp_dispatch1<param_not_found> {
  174. template <class Graph, class P, class T, class R>
  175. static typename edge_capacity_value<Graph, P, T, R>::type
  176. apply
  177. (Graph& g,
  178. typename graph_traits<Graph>::vertex_descriptor src,
  179. typename graph_traits<Graph>::vertex_descriptor sink,
  180. const bgl_named_params<P, T, R>& params,
  181. param_not_found)
  182. {
  183. typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
  184. typedef typename graph_traits<Graph>::vertices_size_type size_type;
  185. size_type n = is_default_param(get_param(params, vertex_predecessor)) ?
  186. num_vertices(g) : 1;
  187. std::vector<edge_descriptor> pred_vec(n);
  188. typedef typename get_param_type< vertex_color_t, bgl_named_params<P,T,R> >::type C;
  189. return edmonds_karp_dispatch2<C>::apply
  190. (g, src, sink,
  191. make_iterator_property_map(pred_vec.begin(), choose_const_pmap
  192. (get_param(params, vertex_index),
  193. g, vertex_index), pred_vec[0]),
  194. params,
  195. get_param(params, vertex_color));
  196. }
  197. };
  198. } // namespace detail
  199. template <class Graph, class P, class T, class R>
  200. typename detail::edge_capacity_value<Graph, P, T, R>::type
  201. edmonds_karp_max_flow
  202. (Graph& g,
  203. typename graph_traits<Graph>::vertex_descriptor src,
  204. typename graph_traits<Graph>::vertex_descriptor sink,
  205. const bgl_named_params<P, T, R>& params)
  206. {
  207. typedef typename get_param_type< vertex_predecessor_t, bgl_named_params<P,T,R> >::type Pred;
  208. return detail::edmonds_karp_dispatch1<Pred>::apply
  209. (g, src, sink, params, get_param(params, vertex_predecessor));
  210. }
  211. template <class Graph>
  212. typename property_traits<
  213. typename property_map<Graph, edge_capacity_t>::const_type
  214. >::value_type
  215. edmonds_karp_max_flow
  216. (Graph& g,
  217. typename graph_traits<Graph>::vertex_descriptor src,
  218. typename graph_traits<Graph>::vertex_descriptor sink)
  219. {
  220. bgl_named_params<int, buffer_param_t> params(0);
  221. return edmonds_karp_max_flow(g, src, sink, params);
  222. }
  223. } // namespace boost
  224. #endif // EDMONDS_KARP_MAX_FLOW_HPP