edmonds_karp_max_flow.hpp 9.9 KB

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