/Src/Dependencies/Boost/boost/graph/edmonds_karp_max_flow.hpp

http://hadesmem.googlecode.com/ · C++ Header · 250 lines · 206 code · 25 blank · 19 comment · 14 complexity · c188ac58da2f39a90c404481f1492a4e MD5 · raw file

  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 = p[sink];
  48. do {
  49. BOOST_USING_STD_MIN();
  50. delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, residual_capacity[e]);
  51. u = source(e, g);
  52. e = p[u];
  53. } while (u != src);
  54. // push delta units of flow along the augmenting path
  55. e = p[sink];
  56. do {
  57. residual_capacity[e] -= delta;
  58. residual_capacity[reverse_edge[e]] += delta;
  59. u = source(e, g);
  60. e = 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. res[*ei] = cap[*ei];
  86. color[sink] = Color::gray();
  87. while (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 (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 += (cap[*ei] - 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<detail::error_property_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. detail::error_property_not_found)
  137. {
  138. typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
  139. typedef typename graph_traits<Graph>::vertices_size_type size_type;
  140. size_type n = is_default_param(get_param(params, vertex_color)) ?
  141. num_vertices(g) : 1;
  142. std::vector<default_color_type> color_vec(n);
  143. return edmonds_karp_max_flow
  144. (g, src, sink,
  145. choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
  146. choose_pmap(get_param(params, edge_residual_capacity),
  147. g, edge_residual_capacity),
  148. choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
  149. make_iterator_property_map(color_vec.begin(), choose_const_pmap
  150. (get_param(params, vertex_index),
  151. g, vertex_index), color_vec[0]),
  152. pred);
  153. }
  154. };
  155. //-------------------------------------------------------------------------
  156. // Handle default for predecessor property map
  157. // use of class here is a VC++ workaround
  158. template <class PredMap>
  159. struct edmonds_karp_dispatch1 {
  160. template <class Graph, class P, class T, class R>
  161. static typename edge_capacity_value<Graph, P, T, R>::type
  162. apply(Graph& g,
  163. typename graph_traits<Graph>::vertex_descriptor src,
  164. typename graph_traits<Graph>::vertex_descriptor sink,
  165. const bgl_named_params<P, T, R>& params,
  166. PredMap pred)
  167. {
  168. typedef typename property_value< bgl_named_params<P,T,R>, vertex_color_t>::type C;
  169. return edmonds_karp_dispatch2<C>::apply
  170. (g, src, sink, pred, params, get_param(params, vertex_color));
  171. }
  172. };
  173. template<>
  174. struct edmonds_karp_dispatch1<detail::error_property_not_found> {
  175. template <class Graph, class P, class T, class R>
  176. static typename edge_capacity_value<Graph, P, T, R>::type
  177. apply
  178. (Graph& g,
  179. typename graph_traits<Graph>::vertex_descriptor src,
  180. typename graph_traits<Graph>::vertex_descriptor sink,
  181. const bgl_named_params<P, T, R>& params,
  182. detail::error_property_not_found)
  183. {
  184. typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
  185. typedef typename graph_traits<Graph>::vertices_size_type size_type;
  186. size_type n = is_default_param(get_param(params, vertex_predecessor)) ?
  187. num_vertices(g) : 1;
  188. std::vector<edge_descriptor> pred_vec(n);
  189. typedef typename property_value< bgl_named_params<P,T,R>, vertex_color_t>::type C;
  190. return edmonds_karp_dispatch2<C>::apply
  191. (g, src, sink,
  192. make_iterator_property_map(pred_vec.begin(), choose_const_pmap
  193. (get_param(params, vertex_index),
  194. g, vertex_index), pred_vec[0]),
  195. params,
  196. get_param(params, vertex_color));
  197. }
  198. };
  199. } // namespace detail
  200. template <class Graph, class P, class T, class R>
  201. typename detail::edge_capacity_value<Graph, P, T, R>::type
  202. edmonds_karp_max_flow
  203. (Graph& g,
  204. typename graph_traits<Graph>::vertex_descriptor src,
  205. typename graph_traits<Graph>::vertex_descriptor sink,
  206. const bgl_named_params<P, T, R>& params)
  207. {
  208. typedef typename property_value< bgl_named_params<P,T,R>, vertex_predecessor_t>::type Pred;
  209. return detail::edmonds_karp_dispatch1<Pred>::apply
  210. (g, src, sink, params, get_param(params, vertex_predecessor));
  211. }
  212. template <class Graph>
  213. typename property_traits<
  214. typename property_map<Graph, edge_capacity_t>::const_type
  215. >::value_type
  216. edmonds_karp_max_flow
  217. (Graph& g,
  218. typename graph_traits<Graph>::vertex_descriptor src,
  219. typename graph_traits<Graph>::vertex_descriptor sink)
  220. {
  221. bgl_named_params<int, buffer_param_t> params(0);
  222. return edmonds_karp_max_flow(g, src, sink, params);
  223. }
  224. } // namespace boost
  225. #endif // EDMONDS_KARP_MAX_FLOW_HPP