push_relabel_max_flow.hpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  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_PUSH_RELABEL_MAX_FLOW_HPP
  10. #define BOOST_PUSH_RELABEL_MAX_FLOW_HPP
  11. #include <boost/config.hpp>
  12. #include <boost/assert.hpp>
  13. #include <vector>
  14. #include <list>
  15. #include <iosfwd>
  16. #include <algorithm> // for std::min and std::max
  17. #include <boost/pending/queue.hpp>
  18. #include <boost/limits.hpp>
  19. #include <boost/graph/graph_concepts.hpp>
  20. #include <boost/graph/named_function_params.hpp>
  21. namespace boost {
  22. namespace detail {
  23. // This implementation is based on Goldberg's
  24. // "On Implementing Push-Relabel Method for the Maximum Flow Problem"
  25. // by B.V. Cherkassky and A.V. Goldberg, IPCO '95, pp. 157--171
  26. // and on the h_prf.c and hi_pr.c code written by the above authors.
  27. // This implements the highest-label version of the push-relabel method
  28. // with the global relabeling and gap relabeling heuristics.
  29. // The terms "rank", "distance", "height" are synonyms in
  30. // Goldberg's implementation, paper and in the CLR. A "layer" is a
  31. // group of vertices with the same distance. The vertices in each
  32. // layer are categorized as active or inactive. An active vertex
  33. // has positive excess flow and its distance is less than n (it is
  34. // not blocked).
  35. template <class Vertex>
  36. struct preflow_layer {
  37. std::list<Vertex> active_vertices;
  38. std::list<Vertex> inactive_vertices;
  39. };
  40. template <class Graph,
  41. class EdgeCapacityMap, // integer value type
  42. class ResidualCapacityEdgeMap,
  43. class ReverseEdgeMap,
  44. class VertexIndexMap, // vertex_descriptor -> integer
  45. class FlowValue>
  46. class push_relabel
  47. {
  48. public:
  49. typedef graph_traits<Graph> Traits;
  50. typedef typename Traits::vertex_descriptor vertex_descriptor;
  51. typedef typename Traits::edge_descriptor edge_descriptor;
  52. typedef typename Traits::vertex_iterator vertex_iterator;
  53. typedef typename Traits::out_edge_iterator out_edge_iterator;
  54. typedef typename Traits::vertices_size_type vertices_size_type;
  55. typedef typename Traits::edges_size_type edges_size_type;
  56. typedef preflow_layer<vertex_descriptor> Layer;
  57. typedef std::vector< Layer > LayerArray;
  58. typedef typename LayerArray::iterator layer_iterator;
  59. typedef typename LayerArray::size_type distance_size_type;
  60. typedef color_traits<default_color_type> ColorTraits;
  61. //=======================================================================
  62. // Some helper predicates
  63. inline bool is_admissible(vertex_descriptor u, vertex_descriptor v) {
  64. return get(distance, u) == get(distance, v) + 1;
  65. }
  66. inline bool is_residual_edge(edge_descriptor a) {
  67. return 0 < get(residual_capacity, a);
  68. }
  69. inline bool is_saturated(edge_descriptor a) {
  70. return get(residual_capacity, a) == 0;
  71. }
  72. //=======================================================================
  73. // Layer List Management Functions
  74. typedef typename std::list<vertex_descriptor>::iterator list_iterator;
  75. void add_to_active_list(vertex_descriptor u, Layer& layer) {
  76. BOOST_USING_STD_MIN();
  77. BOOST_USING_STD_MAX();
  78. layer.active_vertices.push_front(u);
  79. max_active = max BOOST_PREVENT_MACRO_SUBSTITUTION(get(distance, u), max_active);
  80. min_active = min BOOST_PREVENT_MACRO_SUBSTITUTION(get(distance, u), min_active);
  81. layer_list_ptr[u] = layer.active_vertices.begin();
  82. }
  83. void remove_from_active_list(vertex_descriptor u) {
  84. layers[get(distance, u)].active_vertices.erase(layer_list_ptr[u]);
  85. }
  86. void add_to_inactive_list(vertex_descriptor u, Layer& layer) {
  87. layer.inactive_vertices.push_front(u);
  88. layer_list_ptr[u] = layer.inactive_vertices.begin();
  89. }
  90. void remove_from_inactive_list(vertex_descriptor u) {
  91. layers[get(distance, u)].inactive_vertices.erase(layer_list_ptr[u]);
  92. }
  93. //=======================================================================
  94. // initialization
  95. push_relabel(Graph& g_,
  96. EdgeCapacityMap cap,
  97. ResidualCapacityEdgeMap res,
  98. ReverseEdgeMap rev,
  99. vertex_descriptor src_,
  100. vertex_descriptor sink_,
  101. VertexIndexMap idx)
  102. : g(g_), n(num_vertices(g_)), capacity(cap), src(src_), sink(sink_),
  103. index(idx),
  104. excess_flow_data(num_vertices(g_)),
  105. excess_flow(excess_flow_data.begin(), idx),
  106. current_data(num_vertices(g_), out_edges(*vertices(g_).first, g_)),
  107. current(current_data.begin(), idx),
  108. distance_data(num_vertices(g_)),
  109. distance(distance_data.begin(), idx),
  110. color_data(num_vertices(g_)),
  111. color(color_data.begin(), idx),
  112. reverse_edge(rev),
  113. residual_capacity(res),
  114. layers(num_vertices(g_)),
  115. layer_list_ptr_data(num_vertices(g_),
  116. layers.front().inactive_vertices.end()),
  117. layer_list_ptr(layer_list_ptr_data.begin(), idx),
  118. push_count(0), update_count(0), relabel_count(0),
  119. gap_count(0), gap_node_count(0),
  120. work_since_last_update(0)
  121. {
  122. vertex_iterator u_iter, u_end;
  123. // Don't count the reverse edges
  124. edges_size_type m = num_edges(g) / 2;
  125. nm = alpha() * n + m;
  126. // Initialize flow to zero which means initializing
  127. // the residual capacity to equal the capacity.
  128. out_edge_iterator ei, e_end;
  129. for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
  130. for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) {
  131. put(residual_capacity, *ei, get(capacity, *ei));
  132. }
  133. for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
  134. vertex_descriptor u = *u_iter;
  135. put(excess_flow, u, 0);
  136. current[u] = out_edges(u, g);
  137. }
  138. bool overflow_detected = false;
  139. FlowValue test_excess = 0;
  140. out_edge_iterator a_iter, a_end;
  141. for (boost::tie(a_iter, a_end) = out_edges(src, g); a_iter != a_end; ++a_iter)
  142. if (target(*a_iter, g) != src)
  143. test_excess += get(residual_capacity, *a_iter);
  144. if (test_excess > (std::numeric_limits<FlowValue>::max)())
  145. overflow_detected = true;
  146. if (overflow_detected)
  147. put(excess_flow, src, (std::numeric_limits<FlowValue>::max)());
  148. else {
  149. put(excess_flow, src, 0);
  150. for (boost::tie(a_iter, a_end) = out_edges(src, g);
  151. a_iter != a_end; ++a_iter) {
  152. edge_descriptor a = *a_iter;
  153. vertex_descriptor tgt = target(a, g);
  154. if (tgt != src) {
  155. ++push_count;
  156. FlowValue delta = get(residual_capacity, a);
  157. put(residual_capacity, a, get(residual_capacity, a) - delta);
  158. edge_descriptor rev = get(reverse_edge, a);
  159. put(residual_capacity, rev, get(residual_capacity, rev) + delta);
  160. put(excess_flow, tgt, get(excess_flow, tgt) + delta);
  161. }
  162. }
  163. }
  164. max_distance = num_vertices(g) - 1;
  165. max_active = 0;
  166. min_active = n;
  167. for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
  168. vertex_descriptor u = *u_iter;
  169. if (u == sink) {
  170. put(distance, u, 0);
  171. continue;
  172. } else if (u == src && !overflow_detected)
  173. put(distance, u, n);
  174. else
  175. put(distance, u, 1);
  176. if (get(excess_flow, u) > 0)
  177. add_to_active_list(u, layers[1]);
  178. else if (get(distance, u) < n)
  179. add_to_inactive_list(u, layers[1]);
  180. }
  181. } // push_relabel constructor
  182. //=======================================================================
  183. // This is a breadth-first search over the residual graph
  184. // (well, actually the reverse of the residual graph).
  185. // Would be cool to have a graph view adaptor for hiding certain
  186. // edges, like the saturated (non-residual) edges in this case.
  187. // Goldberg's implementation abused "distance" for the coloring.
  188. void global_distance_update()
  189. {
  190. BOOST_USING_STD_MAX();
  191. ++update_count;
  192. vertex_iterator u_iter, u_end;
  193. for (boost::tie(u_iter,u_end) = vertices(g); u_iter != u_end; ++u_iter) {
  194. put(color, *u_iter, ColorTraits::white());
  195. put(distance, *u_iter, n);
  196. }
  197. put(color, sink, ColorTraits::gray());
  198. put(distance, sink, 0);
  199. for (distance_size_type l = 0; l <= max_distance; ++l) {
  200. layers[l].active_vertices.clear();
  201. layers[l].inactive_vertices.clear();
  202. }
  203. max_distance = max_active = 0;
  204. min_active = n;
  205. Q.push(sink);
  206. while (! Q.empty()) {
  207. vertex_descriptor u = Q.top();
  208. Q.pop();
  209. distance_size_type d_v = get(distance, u) + 1;
  210. out_edge_iterator ai, a_end;
  211. for (boost::tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai) {
  212. edge_descriptor a = *ai;
  213. vertex_descriptor v = target(a, g);
  214. if (get(color, v) == ColorTraits::white()
  215. && is_residual_edge(get(reverse_edge, a))) {
  216. put(distance, v, d_v);
  217. put(color, v, ColorTraits::gray());
  218. current[v] = out_edges(v, g);
  219. max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(d_v, max_distance);
  220. if (get(excess_flow, v) > 0)
  221. add_to_active_list(v, layers[d_v]);
  222. else
  223. add_to_inactive_list(v, layers[d_v]);
  224. Q.push(v);
  225. }
  226. }
  227. }
  228. } // global_distance_update()
  229. //=======================================================================
  230. // This function is called "push" in Goldberg's h_prf implementation,
  231. // but it is called "discharge" in the paper and in hi_pr.c.
  232. void discharge(vertex_descriptor u)
  233. {
  234. BOOST_ASSERT(get(excess_flow, u) > 0);
  235. while (1) {
  236. out_edge_iterator ai, ai_end;
  237. for (boost::tie(ai, ai_end) = current[u]; ai != ai_end; ++ai) {
  238. edge_descriptor a = *ai;
  239. if (is_residual_edge(a)) {
  240. vertex_descriptor v = target(a, g);
  241. if (is_admissible(u, v)) {
  242. ++push_count;
  243. if (v != sink && get(excess_flow, v) == 0) {
  244. remove_from_inactive_list(v);
  245. add_to_active_list(v, layers[get(distance, v)]);
  246. }
  247. push_flow(a);
  248. if (get(excess_flow, u) == 0)
  249. break;
  250. }
  251. }
  252. } // for out_edges of i starting from current
  253. Layer& layer = layers[get(distance, u)];
  254. distance_size_type du = get(distance, u);
  255. if (ai == ai_end) { // i must be relabeled
  256. relabel_distance(u);
  257. if (layer.active_vertices.empty()
  258. && layer.inactive_vertices.empty())
  259. gap(du);
  260. if (get(distance, u) == n)
  261. break;
  262. } else { // i is no longer active
  263. current[u].first = ai;
  264. add_to_inactive_list(u, layer);
  265. break;
  266. }
  267. } // while (1)
  268. } // discharge()
  269. //=======================================================================
  270. // This corresponds to the "push" update operation of the paper,
  271. // not the "push" function in Goldberg's h_prf.c implementation.
  272. // The idea is to push the excess flow from from vertex u to v.
  273. void push_flow(edge_descriptor u_v)
  274. {
  275. vertex_descriptor
  276. u = source(u_v, g),
  277. v = target(u_v, g);
  278. BOOST_USING_STD_MIN();
  279. FlowValue flow_delta
  280. = min BOOST_PREVENT_MACRO_SUBSTITUTION(get(excess_flow, u), get(residual_capacity, u_v));
  281. put(residual_capacity, u_v, get(residual_capacity, u_v) - flow_delta);
  282. edge_descriptor rev = get(reverse_edge, u_v);
  283. put(residual_capacity, rev, get(residual_capacity, rev) + flow_delta);
  284. put(excess_flow, u, get(excess_flow, u) - flow_delta);
  285. put(excess_flow, v, get(excess_flow, v) + flow_delta);
  286. } // push_flow()
  287. //=======================================================================
  288. // The main purpose of this routine is to set distance[v]
  289. // to the smallest value allowed by the valid labeling constraints,
  290. // which are:
  291. // distance[t] = 0
  292. // distance[u] <= distance[v] + 1 for every residual edge (u,v)
  293. //
  294. distance_size_type relabel_distance(vertex_descriptor u)
  295. {
  296. BOOST_USING_STD_MAX();
  297. ++relabel_count;
  298. work_since_last_update += beta();
  299. distance_size_type min_distance = num_vertices(g);
  300. put(distance, u, min_distance);
  301. // Examine the residual out-edges of vertex i, choosing the
  302. // edge whose target vertex has the minimal distance.
  303. out_edge_iterator ai, a_end, min_edge_iter;
  304. for (boost::tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai) {
  305. ++work_since_last_update;
  306. edge_descriptor a = *ai;
  307. vertex_descriptor v = target(a, g);
  308. if (is_residual_edge(a) && get(distance, v) < min_distance) {
  309. min_distance = get(distance, v);
  310. min_edge_iter = ai;
  311. }
  312. }
  313. ++min_distance;
  314. if (min_distance < n) {
  315. put(distance, u, min_distance); // this is the main action
  316. current[u].first = min_edge_iter;
  317. max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(min_distance, max_distance);
  318. }
  319. return min_distance;
  320. } // relabel_distance()
  321. //=======================================================================
  322. // cleanup beyond the gap
  323. void gap(distance_size_type empty_distance)
  324. {
  325. ++gap_count;
  326. distance_size_type r; // distance of layer before the current layer
  327. r = empty_distance - 1;
  328. // Set the distance for the vertices beyond the gap to "infinity".
  329. for (layer_iterator l = layers.begin() + empty_distance + 1;
  330. l < layers.begin() + max_distance; ++l) {
  331. list_iterator i;
  332. for (i = l->inactive_vertices.begin();
  333. i != l->inactive_vertices.end(); ++i) {
  334. put(distance, *i, n);
  335. ++gap_node_count;
  336. }
  337. l->inactive_vertices.clear();
  338. }
  339. max_distance = r;
  340. max_active = r;
  341. }
  342. //=======================================================================
  343. // This is the core part of the algorithm, "phase one".
  344. FlowValue maximum_preflow()
  345. {
  346. work_since_last_update = 0;
  347. while (max_active >= min_active) { // "main" loop
  348. Layer& layer = layers[max_active];
  349. list_iterator u_iter = layer.active_vertices.begin();
  350. if (u_iter == layer.active_vertices.end())
  351. --max_active;
  352. else {
  353. vertex_descriptor u = *u_iter;
  354. remove_from_active_list(u);
  355. discharge(u);
  356. if (work_since_last_update * global_update_frequency() > nm) {
  357. global_distance_update();
  358. work_since_last_update = 0;
  359. }
  360. }
  361. } // while (max_active >= min_active)
  362. return get(excess_flow, sink);
  363. } // maximum_preflow()
  364. //=======================================================================
  365. // remove excess flow, the "second phase"
  366. // This does a DFS on the reverse flow graph of nodes with excess flow.
  367. // If a cycle is found, cancel it.
  368. // Return the nodes with excess flow in topological order.
  369. //
  370. // Unlike the prefl_to_flow() implementation, we use
  371. // "color" instead of "distance" for the DFS labels
  372. // "parent" instead of nl_prev for the DFS tree
  373. // "topo_next" instead of nl_next for the topological ordering
  374. void convert_preflow_to_flow()
  375. {
  376. vertex_iterator u_iter, u_end;
  377. out_edge_iterator ai, a_end;
  378. vertex_descriptor r, restart, u;
  379. std::vector<vertex_descriptor> parent(n);
  380. std::vector<vertex_descriptor> topo_next(n);
  381. vertex_descriptor tos(parent[0]),
  382. bos(parent[0]); // bogus initialization, just to avoid warning
  383. bool bos_null = true;
  384. // handle self-loops
  385. for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
  386. for (boost::tie(ai, a_end) = out_edges(*u_iter, g); ai != a_end; ++ai)
  387. if (target(*ai, g) == *u_iter)
  388. put(residual_capacity, *ai, get(capacity, *ai));
  389. // initialize
  390. for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
  391. u = *u_iter;
  392. put(color, u, ColorTraits::white());
  393. parent[get(index, u)] = u;
  394. current[u] = out_edges(u, g);
  395. }
  396. // eliminate flow cycles and topologically order the vertices
  397. for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
  398. u = *u_iter;
  399. if (get(color, u) == ColorTraits::white()
  400. && get(excess_flow, u) > 0
  401. && u != src && u != sink ) {
  402. r = u;
  403. put(color, r, ColorTraits::gray());
  404. while (1) {
  405. for (; current[u].first != current[u].second; ++current[u].first) {
  406. edge_descriptor a = *current[u].first;
  407. if (get(capacity, a) == 0 && is_residual_edge(a)) {
  408. vertex_descriptor v = target(a, g);
  409. if (get(color, v) == ColorTraits::white()) {
  410. put(color, v, ColorTraits::gray());
  411. parent[get(index, v)] = u;
  412. u = v;
  413. break;
  414. } else if (get(color, v) == ColorTraits::gray()) {
  415. // find minimum flow on the cycle
  416. FlowValue delta = get(residual_capacity, a);
  417. while (1) {
  418. BOOST_USING_STD_MIN();
  419. delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, get(residual_capacity, *current[v].first));
  420. if (v == u)
  421. break;
  422. else
  423. v = target(*current[v].first, g);
  424. }
  425. // remove delta flow units
  426. v = u;
  427. while (1) {
  428. a = *current[v].first;
  429. put(residual_capacity, a, get(residual_capacity, a) - delta);
  430. edge_descriptor rev = get(reverse_edge, a);
  431. put(residual_capacity, rev, get(residual_capacity, rev) + delta);
  432. v = target(a, g);
  433. if (v == u)
  434. break;
  435. }
  436. // back-out of DFS to the first saturated edge
  437. restart = u;
  438. for (v = target(*current[u].first, g); v != u; v = target(a, g)){
  439. a = *current[v].first;
  440. if (get(color, v) == ColorTraits::white()
  441. || is_saturated(a)) {
  442. put(color, target(*current[v].first, g), ColorTraits::white());
  443. if (get(color, v) != ColorTraits::white())
  444. restart = v;
  445. }
  446. }
  447. if (restart != u) {
  448. u = restart;
  449. ++current[u].first;
  450. break;
  451. }
  452. } // else if (color[v] == ColorTraits::gray())
  453. } // if (get(capacity, a) == 0 ...
  454. } // for out_edges(u, g) (though "u" changes during loop)
  455. if ( current[u].first == current[u].second ) {
  456. // scan of i is complete
  457. put(color, u, ColorTraits::black());
  458. if (u != src) {
  459. if (bos_null) {
  460. bos = u;
  461. bos_null = false;
  462. tos = u;
  463. } else {
  464. topo_next[get(index, u)] = tos;
  465. tos = u;
  466. }
  467. }
  468. if (u != r) {
  469. u = parent[get(index, u)];
  470. ++current[u].first;
  471. } else
  472. break;
  473. }
  474. } // while (1)
  475. } // if (color[u] == white && excess_flow[u] > 0 & ...)
  476. } // for all vertices in g
  477. // return excess flows
  478. // note that the sink is not on the stack
  479. if (! bos_null) {
  480. for (u = tos; u != bos; u = topo_next[get(index, u)]) {
  481. boost::tie(ai, a_end) = out_edges(u, g);
  482. while (get(excess_flow, u) > 0 && ai != a_end) {
  483. if (get(capacity, *ai) == 0 && is_residual_edge(*ai))
  484. push_flow(*ai);
  485. ++ai;
  486. }
  487. }
  488. // do the bottom
  489. u = bos;
  490. boost::tie(ai, a_end) = out_edges(u, g);
  491. while (get(excess_flow, u) > 0 && ai != a_end) {
  492. if (get(capacity, *ai) == 0 && is_residual_edge(*ai))
  493. push_flow(*ai);
  494. ++ai;
  495. }
  496. }
  497. } // convert_preflow_to_flow()
  498. //=======================================================================
  499. inline bool is_flow()
  500. {
  501. vertex_iterator u_iter, u_end;
  502. out_edge_iterator ai, a_end;
  503. // check edge flow values
  504. for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
  505. for (boost::tie(ai, a_end) = out_edges(*u_iter, g); ai != a_end; ++ai) {
  506. edge_descriptor a = *ai;
  507. if (get(capacity, a) > 0)
  508. if ((get(residual_capacity, a) + get(residual_capacity, get(reverse_edge, a))
  509. != get(capacity, a) + get(capacity, get(reverse_edge, a)))
  510. || (get(residual_capacity, a) < 0)
  511. || (get(residual_capacity, get(reverse_edge, a)) < 0))
  512. return false;
  513. }
  514. }
  515. // check conservation
  516. FlowValue sum;
  517. for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
  518. vertex_descriptor u = *u_iter;
  519. if (u != src && u != sink) {
  520. if (get(excess_flow, u) != 0)
  521. return false;
  522. sum = 0;
  523. for (boost::tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai)
  524. if (get(capacity, *ai) > 0)
  525. sum -= get(capacity, *ai) - get(residual_capacity, *ai);
  526. else
  527. sum += get(residual_capacity, *ai);
  528. if (get(excess_flow, u) != sum)
  529. return false;
  530. }
  531. }
  532. return true;
  533. } // is_flow()
  534. bool is_optimal() {
  535. // check if mincut is saturated...
  536. global_distance_update();
  537. return get(distance, src) >= n;
  538. }
  539. void print_statistics(std::ostream& os) const {
  540. os << "pushes: " << push_count << std::endl
  541. << "relabels: " << relabel_count << std::endl
  542. << "updates: " << update_count << std::endl
  543. << "gaps: " << gap_count << std::endl
  544. << "gap nodes: " << gap_node_count << std::endl
  545. << std::endl;
  546. }
  547. void print_flow_values(std::ostream& os) const {
  548. os << "flow values" << std::endl;
  549. vertex_iterator u_iter, u_end;
  550. out_edge_iterator ei, e_end;
  551. for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
  552. for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
  553. if (get(capacity, *ei) > 0)
  554. os << *u_iter << " " << target(*ei, g) << " "
  555. << (get(capacity, *ei) - get(residual_capacity, *ei)) << std::endl;
  556. os << std::endl;
  557. }
  558. //=======================================================================
  559. Graph& g;
  560. vertices_size_type n;
  561. vertices_size_type nm;
  562. EdgeCapacityMap capacity;
  563. vertex_descriptor src;
  564. vertex_descriptor sink;
  565. VertexIndexMap index;
  566. // will need to use random_access_property_map with these
  567. std::vector< FlowValue > excess_flow_data;
  568. iterator_property_map<typename std::vector<FlowValue>::iterator, VertexIndexMap> excess_flow;
  569. std::vector< std::pair<out_edge_iterator, out_edge_iterator> > current_data;
  570. iterator_property_map<
  571. typename std::vector< std::pair<out_edge_iterator, out_edge_iterator> >::iterator,
  572. VertexIndexMap> current;
  573. std::vector< distance_size_type > distance_data;
  574. iterator_property_map<
  575. typename std::vector< distance_size_type >::iterator,
  576. VertexIndexMap> distance;
  577. std::vector< default_color_type > color_data;
  578. iterator_property_map<
  579. std::vector< default_color_type >::iterator,
  580. VertexIndexMap> color;
  581. // Edge Property Maps that must be interior to the graph
  582. ReverseEdgeMap reverse_edge;
  583. ResidualCapacityEdgeMap residual_capacity;
  584. LayerArray layers;
  585. std::vector< list_iterator > layer_list_ptr_data;
  586. iterator_property_map<typename std::vector< list_iterator >::iterator, VertexIndexMap> layer_list_ptr;
  587. distance_size_type max_distance; // maximal distance
  588. distance_size_type max_active; // maximal distance with active node
  589. distance_size_type min_active; // minimal distance with active node
  590. boost::queue<vertex_descriptor> Q;
  591. // Statistics counters
  592. long push_count;
  593. long update_count;
  594. long relabel_count;
  595. long gap_count;
  596. long gap_node_count;
  597. inline double global_update_frequency() { return 0.5; }
  598. inline vertices_size_type alpha() { return 6; }
  599. inline long beta() { return 12; }
  600. long work_since_last_update;
  601. };
  602. } // namespace detail
  603. template <class Graph,
  604. class CapacityEdgeMap, class ResidualCapacityEdgeMap,
  605. class ReverseEdgeMap, class VertexIndexMap>
  606. typename property_traits<CapacityEdgeMap>::value_type
  607. push_relabel_max_flow
  608. (Graph& g,
  609. typename graph_traits<Graph>::vertex_descriptor src,
  610. typename graph_traits<Graph>::vertex_descriptor sink,
  611. CapacityEdgeMap cap, ResidualCapacityEdgeMap res,
  612. ReverseEdgeMap rev, VertexIndexMap index_map)
  613. {
  614. typedef typename property_traits<CapacityEdgeMap>::value_type FlowValue;
  615. detail::push_relabel<Graph, CapacityEdgeMap, ResidualCapacityEdgeMap,
  616. ReverseEdgeMap, VertexIndexMap, FlowValue>
  617. algo(g, cap, res, rev, src, sink, index_map);
  618. FlowValue flow = algo.maximum_preflow();
  619. algo.convert_preflow_to_flow();
  620. BOOST_ASSERT(algo.is_flow());
  621. BOOST_ASSERT(algo.is_optimal());
  622. return flow;
  623. } // push_relabel_max_flow()
  624. template <class Graph, class P, class T, class R>
  625. typename detail::edge_capacity_value<Graph, P, T, R>::type
  626. push_relabel_max_flow
  627. (Graph& g,
  628. typename graph_traits<Graph>::vertex_descriptor src,
  629. typename graph_traits<Graph>::vertex_descriptor sink,
  630. const bgl_named_params<P, T, R>& params)
  631. {
  632. return push_relabel_max_flow
  633. (g, src, sink,
  634. choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
  635. choose_pmap(get_param(params, edge_residual_capacity),
  636. g, edge_residual_capacity),
  637. choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
  638. choose_const_pmap(get_param(params, vertex_index), g, vertex_index)
  639. );
  640. }
  641. template <class Graph>
  642. typename property_traits<
  643. typename property_map<Graph, edge_capacity_t>::const_type
  644. >::value_type
  645. push_relabel_max_flow
  646. (Graph& g,
  647. typename graph_traits<Graph>::vertex_descriptor src,
  648. typename graph_traits<Graph>::vertex_descriptor sink)
  649. {
  650. bgl_named_params<int, buffer_param_t> params(0); // bogus empty param
  651. return push_relabel_max_flow(g, src, sink, params);
  652. }
  653. } // namespace boost
  654. #endif // BOOST_PUSH_RELABEL_MAX_FLOW_HPP