boykov_kolmogorov_max_flow.html 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  2. <HTML>
  3. <HEAD>
  4. <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-15">
  5. <TITLE>Boost Graph Library: Boykov-Kolmogorov Maximum Flow</TITLE>
  6. <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.0 (Linux)">
  7. <META NAME="CREATED" CONTENT="20060820;17315200">
  8. <META NAME="CHANGEDBY" CONTENT="Stephan Diederich">
  9. <META NAME="CHANGED" CONTENT="20060820;23125100">
  10. <!--
  11. // Copyright (c) 2006 Stephan Diederich
  12. //
  13. // This documentation may be used under either of the following two licences:
  14. //
  15. // Permission is hereby granted, free of charge, to any person
  16. // obtaining a copy of this software and associated documentation
  17. // files (the "Software"), to deal in the Software without
  18. // restriction, including without limitation the rights to use,
  19. // copy, modify, merge, publish, distribute, sublicense, and/or
  20. // sell copies of the Software, and to permit persons to whom the
  21. // Software is furnished to do so, subject to the following
  22. // conditions:
  23. //
  24. // The above copyright notice and this permission notice shall be
  25. // included in all copies or substantial portions of the Software.
  26. //
  27. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  28. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  29. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  30. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  31. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  32. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  33. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  34. // OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE.
  35. //
  36. // Or:
  37. //
  38. // Distributed under the Boost Software License, Version 1.0.
  39. // (See accompanying file LICENSE_1_0.txt or copy at
  40. // http://www.boost.org/LICENSE_1_0.txt)
  41. -->
  42. <STYLE>
  43. <!--
  44. TD P { color: #000000 }
  45. H1 { color: #000000 }
  46. P { color: #000000 }
  47. PRE { color: #000000 }
  48. H3 { color: #000000 }
  49. BLOCKQUOTE { color: #000000 }
  50. A:link { color: #0000ee }
  51. A:visited { color: #551a8b }
  52. -->
  53. </STYLE>
  54. </HEAD>
  55. <BODY LANG="de-DE" TEXT="#000000" LINK="#0000ee" VLINK="#551a8b" BGCOLOR="#ffffff" DIR="LTR">
  56. <P><IMG SRC="../../../boost.png" NAME="Grafik1" ALT="C++ Boost" ALIGN=BOTTOM WIDTH=277 HEIGHT=86 BORDER=0>
  57. </P>
  58. <H1><A NAME="sec:boykov_kolmogorov_max_flow"></A><TT>boykov_kolmogorov_max_flow</TT>
  59. </H1>
  60. <PRE><I>// named parameter version</I>
  61. template &lt;class Graph, class P, class T, class R&gt;
  62. typename property_traits&lt;typename property_map&lt;Graph, edge_capacity_t&gt;::const_type&gt;::value_type
  63. boykov_kolmogorov_max_flow(Graph&amp; g,
  64. typename graph_traits&lt;Graph&gt;::vertex_descriptor src,
  65. typename graph_traits&lt;Graph&gt;::vertex_descriptor sink,
  66. const bgl_named_params&lt;P, T, R&gt;&amp; params = <I>all defaults</I>)
  67. <I>// non-named parameter version</I>
  68. template &lt;class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap, class ReverseEdgeMap,
  69. class PredecessorMap, class ColorMap, class DistanceMap, class IndexMap&gt;
  70. typename property_traits&lt;CapacityEdgeMap&gt;::value_type
  71. boykov_kolmogorov_max_flow(Graph&amp; g,
  72. CapacityEdgeMap cap,
  73. ResidualCapacityEdgeMap res_cap,
  74. ReverseEdgeMap rev_map,
  75. PredecessorMap pre_map,
  76. ColorMap color,
  77. DistanceMap dist,
  78. IndexMap idx,
  79. typename graph_traits &lt;Graph&gt;::vertex_descriptor src,
  80. typename graph_traits &lt;Graph &gt;::vertex_descriptor sink)</PRE><P>
  81. <FONT SIZE=3>Additional overloaded versions for non-named parameters
  82. are provided (without DistanceMap/ColorMap/DistanceMap; for those
  83. iterator_property_maps with the provided index map are used)</FONT></P>
  84. <P>The <TT>boykov_kolmogorov_max_flow()</TT> function calculates the maximum
  85. flow of a network. See Section <A HREF="graph_theory_review.html#sec:network-flow-algorithms">Network
  86. Flow Algorithms</A> for a description of maximum flow. The calculated
  87. maximum flow will be the return value of the function. The function
  88. also calculates the flow values <I>f(u,v)</I> for all <I>(u,v)</I> in
  89. <I>E</I>, which are returned in the form of the residual capacity
  90. <I>r(u,v) = c(u,v) - f(u,v)</I>.
  91. </P>
  92. <P><B>Requirements:</B><BR>The directed graph <I>G=(V,E)</I> that
  93. represents the network must include a reverse edge for every edge in
  94. <I>E</I>. That is, the input graph should be <I>G<SUB>in</SUB> =
  95. (V,{E U E<SUP>T</SUP>})</I>. The <TT>ReverseEdgeMap</TT> argument <TT>rev</TT>
  96. must map each edge in the original graph to its reverse edge, that is
  97. <I>(u,v) -&gt; (v,u)</I> for all <I>(u,v)</I> in <I>E</I>.
  98. </P>
  99. <P>Remarks: While the push-relabel method states that each edge in <I>E<SUP>T</SUP></I>
  100. has to have capacity of 0, the reverse edges for this algorithm ARE
  101. allowed to carry capacities. If there are already reverse edges in
  102. the input Graph <I><FONT FACE="Courier New, monospace">G</FONT></I>,
  103. those can be used. This can halve the amount of edges and will
  104. noticeably increase the performance.</P>
  105. <P>
  106. <B>Algorithm description:</B><BR>The Boykov-Kolmogorov max-flow (or often
  107. BK max-flow) algorithm is a variety of the augmenting-path algorithm. Standard
  108. augmenting path algorithms find shortest paths from source to sink vertex and
  109. augment them by subtracting the bottleneck capacity found on that path from the
  110. residual capacities of each edge and adding it to the total flow. Additionally
  111. the minimum capacity is added to the residual capacity of the reverse edges. If
  112. no more paths in the residual-edge tree are found, the algorithm terminates.
  113. Instead of finding a new shortest path from source to sink in the graph in each
  114. iteration, the Boykov-Kolmogorov algorithm keeps the already found paths as
  115. follows:</P>
  116. <P>The algorithm builds up two search trees, a source-tree and a
  117. sink-tree. Each vertex has a label (stored in <I>ColorMap</I>) to
  118. which tree it belongs and a status-flag if this vertex is active or
  119. passive. In the beginning of the algorithm only the source and the
  120. sink are colored (source==black, sink==white) and have active status.
  121. All other vertices are colored gray. The algorithm consists of three
  122. phases:</P>
  123. <P><I>grow-phase</I>: In this phase active vertices are allowed to
  124. acquire neighbor vertices that are connected through an edge that has
  125. a capacity-value greater than zero. Acquiring means that those vertices
  126. become active and belong now to the search tree of the current
  127. active vertex. If there are no more valid connections to neighbor
  128. vertices, the current vertex becomes passive and the grow phase
  129. continues with the next active vertex. The grow phase terminates if
  130. there are no more active vertices left or a vertex discovers a vertex
  131. from the other search tree through an unsaturated edge. In this case
  132. a path from source to sink is found.</P>
  133. <P><I>augment-phase</I>: This phase augments the path that was found
  134. in the grow phase. First it finds the bottleneck capacity of the
  135. found path, and then it updates the residual-capacity of the edges
  136. from this path by subtracting the bottleneck capacity from the
  137. residual capacity. Furthermore the residual capacity of the reverse
  138. edges are updated by adding the bottleneck capacity. This phase can
  139. destroy the built up search trees, as it creates at least one
  140. saturated edge. That means, that the search trees collapse to
  141. forests, because a condition for the search trees is, that each
  142. vertex in them has a valid (=non-saturated) connection to a terminal.</P>
  143. <P><I>adoption-phase</I>: Here the search trees are reconstructed. A
  144. simple solution would be to mark all vertices coming after the first
  145. orphan in the found path free vertices (gray). A more sophisticated
  146. solution is to give those orphans new parents: The neighbor vertices
  147. are checked if they have a valid connection to the same terminal like
  148. this vertex had (a path with unsaturated edges). If there is one,
  149. this vertex becomes the new parent of the current orphan and this
  150. forest is re-included into the search tree. If no new valid parent is
  151. found, this vertex becomes a free vertex (marked gray), and it's
  152. children become orphans. The adoption phase terminates if there are
  153. no more orphans.</P>
  154. <P><IMG SRC="figs/bk_max_flow.gif" NAME="Grafik2" ALIGN=LEFT WIDTH=827 HEIGHT=311 BORDER=0><BR CLEAR=LEFT><B>Details:</B></P>
  155. <UL>
  156. <LI><P>Marking heuristics: A timestamp is stored for each vertex
  157. which shows in which iteration of the algorithm the distance to the
  158. corresponding terminal was calculated.
  159. </P>
  160. <UL>
  161. <LI><P>This distance is used and gets calculated in the
  162. adoption-phase. In order to find a valid new parent for an orphan,
  163. the possible parent is checked for a connection to the terminal to
  164. which tree it belongs. If there is such a connection, the path is
  165. tagged with the current time-stamp, and the distance value. If
  166. another orphan has to find a parent and it comes across a vertex
  167. with a current timestamp, this information is used.</P>
  168. <LI><P>The distance is also used in the grow-phase. If a vertex
  169. comes across another vertex of the same tree while searching for
  170. new vertices, the other's distance is compared to its distance. If
  171. it is smaller, that other vertex becomes the new parent of the
  172. current. This can decrease the length of the search paths, and so
  173. amount of adoptions.</P>
  174. </UL>
  175. <LI><P>Ordering of orphans: As described above, the augment-phase
  176. and the adoption phase can create orphans. The orphans the
  177. augment-phase generates, are ordered according to their distance to
  178. the terminals (smallest first). This combined with the
  179. distance/timestamp heuristics results in the possibility for not
  180. having to recheck terminal-connections too often. New orphans which
  181. are generated in adoption phase are processed before orphans from
  182. the main queue for the same reason.</P>
  183. </UL>
  184. <P><BR><B>Implementation notes:</B></P>
  185. <P>The algorithm is mainly implemented as described by Boykov and Kolmogorov in
  186. [<a href="bibliography.html#boykov-kolmogorov04">69</a>]. An extended version
  187. can be found in the PhD Thesis of Kolmogorov [<A HREF="bibliography.html#kolmogorov03">68</a>].
  188. The following changes are made to improve performance:</P>
  189. <UL>
  190. <LI>initialization: the algorithm first augments all paths from
  191. source-&gt;sink and all paths from source-&gt;VERTEX-&gt;sink. This
  192. improves especially graph-cuts used in image vision where nearly
  193. each vertex has a source and sink connect. During this step, all
  194. vertices that have an unsaturated connection from source are added
  195. to the active vertex list and so the source is not.</LI>
  196. <LI>active vertices: Boykov-Kolmogorov uses two lists for active nodes
  197. and states that new active vertices are added to the rear of the
  198. second. Fetching an active vertex is done from the beginning of the
  199. first list. If the first list is empty, it is exchanged by the
  200. second. This implementation uses just one list.</LI>
  201. <LI>grow-phase: In the grow phase the first vertex in the
  202. active-list is taken and all outgoing edges are checked if they are
  203. unsaturated. This decreases performance for graphs with high-edge
  204. density. This implementation stores the last accessed edge and
  205. continues with it, if the first vertex in the active-list is the
  206. same one as during the last grow-phase.</LI>
  207. </UL>
  208. <H3>Where Defined</H3>
  209. <P><TT><A HREF="../../../boost/graph/boykov_kolmogorov_max_flow.hpp">boost/graph/boykov_kolmogorov_max_flow.hpp</A></TT>
  210. </P>
  211. <H3>Parameters</H3>
  212. <P>IN: <TT>Graph&amp; g</TT>
  213. </P>
  214. <BLOCKQUOTE>A directed graph. The graph's type must be a model of
  215. <A HREF="VertexListGraph.html">Vertex List Graph</A>, <A HREF="EdgeListGraph.html">Edge
  216. List Graph</A> and <A HREF="IncidenceGraph.html">Incidence Graph</A>.
  217. For each edge <I>(u,v)</I> in the graph, the reverse edge <I>(v,u)</I>
  218. must also be in the graph. Performance of the algorithm will be slightly
  219. improved if the graph type also models <a href="AdjacencyMatrix.html">Adjacency
  220. Matrix</a>.
  221. </BLOCKQUOTE>
  222. <P>IN: <TT>vertex_descriptor src</TT>
  223. </P>
  224. <BLOCKQUOTE>The source vertex for the flow network graph.
  225. </BLOCKQUOTE>
  226. <P>IN: <TT>vertex_descriptor sink</TT>
  227. </P>
  228. <BLOCKQUOTE>The sink vertex for the flow network graph.
  229. </BLOCKQUOTE>
  230. <H3>Named Parameters</H3>
  231. <P>IN: <TT>edge_capacity(EdgeCapacityMap cap)</TT>
  232. </P>
  233. <BLOCKQUOTE>The edge capacity property map. The type must be a model
  234. of a constant <A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue
  235. Property Map</A>. The key type of the map must be the graph's edge
  236. descriptor type.<BR><B>Default:</B> <TT>get(edge_capacity, g)</TT>
  237. </BLOCKQUOTE>
  238. <P>OUT: <TT>edge_residual_capacity(ResidualCapacityEdgeMap res)</TT>
  239. </P>
  240. <BLOCKQUOTE>The edge residual capacity property map. The type must be
  241. a model of a mutable <A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue
  242. Property Map</A>. The key type of the map must be the graph's edge
  243. descriptor type.<BR><B>Default:</B> <TT>get(edge_residual_capacity,
  244. g)</TT>
  245. </BLOCKQUOTE>
  246. <P>IN: <TT>edge_reverse(ReverseEdgeMap rev)</TT>
  247. </P>
  248. <BLOCKQUOTE>An edge property map that maps every edge <I>(u,v)</I> in
  249. the graph to the reverse edge <I>(v,u)</I>. The map must be a model
  250. of constant <A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue
  251. Property Map</A>. The key type of the map must be the graph's edge
  252. descriptor type.<BR><B>Default:</B> <TT>get(edge_reverse, g)</TT>
  253. </BLOCKQUOTE>
  254. <P>UTIL: <TT>vertex_predecessor(PredecessorMap pre_map)</TT>
  255. </P>
  256. <BLOCKQUOTE>A vertex property map that stores the edge to the vertex'
  257. predecessor. The map must be a model of mutable <A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue
  258. Property Map</A>. The key type of the map must be the graph's vertex
  259. descriptor type.<BR><B>Default:</B> <TT>get(vertex_predecessor, g)</TT>
  260. </BLOCKQUOTE>
  261. <P>OUT/UTIL: <TT>vertex_color(ColorMap color)</TT>
  262. </P>
  263. <BLOCKQUOTE>A vertex property map that stores a color for edge
  264. vertex. If the color of a vertex after running the algorithm is black
  265. the vertex belongs to the source tree else it belongs to the
  266. sink-tree (used for minimum cuts). The map must be a model of mutable
  267. <A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue Property
  268. Map</A>. The key type of the map must be the graph's vertex
  269. descriptor type.<BR><B>Default:</B> <TT>get(vertex_color, g)</TT>
  270. </BLOCKQUOTE>
  271. <P>UTIL: <TT>vertex_distance(DistanceMap dist)</TT>
  272. </P>
  273. <BLOCKQUOTE>A vertex property map that stores the distance to the
  274. corresponding terminal. It's a utility-map for speeding up the
  275. algorithm. The map must be a model of mutable <A HREF="../../property_map/doc/LvaluePropertyMap.html">Lvalue
  276. Property Map</A>. The key type of the map must be the graph's vertex
  277. descriptor type.<BR><B>Default:</B> <TT>get(vertex_distance, g)</TT>
  278. </BLOCKQUOTE>
  279. <P>IN: <TT>vertex_index(VertexIndexMap index_map)</TT>
  280. </P>
  281. <BLOCKQUOTE>Maps each vertex of the graph to a unique integer in the
  282. range <TT>[0, num_vertices(g))</TT>. The map must be a model of
  283. constant <A HREF="../../property_map/doc/LvaluePropertyMap.html">LvaluePropertyMap</A>.
  284. The key type of the map must be the graph's vertex descriptor
  285. type.<BR><B>Default:</B> <TT>get(vertex_index, g)</TT>
  286. </BLOCKQUOTE>
  287. <H3>Example</H3>
  288. <P>This reads an example maximum flow problem (a graph with edge
  289. capacities) from a file in the DIMACS format (<TT><A HREF="../example/max_flow.dat">example/max_flow.dat</A></TT>).
  290. The source for this example can be found in
  291. <TT><A HREF="../example/boykov_kolmogorov-eg.cpp">example/boykov_kolmogorov-eg.cpp</A></TT>.
  292. </P>
  293. <PRE>#include &lt;boost/config.hpp&gt;
  294. #include &lt;iostream&gt;
  295. #include &lt;string&gt;
  296. #include &lt;boost/graph/adjacency_list.hpp&gt;
  297. #include &lt;boost/graph/boykov_kolmogorov_max_flow.hpp&gt;
  298. #include &lt;boost/graph/read_dimacs.hpp&gt;
  299. #include &lt;boost/graph/graph_utility.hpp&gt;
  300. int
  301. main()
  302. {
  303. using namespace boost;
  304. typedef adjacency_list_traits &lt; vecS, vecS, directedS &gt; Traits;
  305. typedef adjacency_list &lt; vecS, vecS, directedS,
  306. property &lt; vertex_name_t, std::string,
  307. property &lt; vertex_index_t, long,
  308. property &lt; vertex_color_t, boost::default_color_type,
  309. property &lt; vertex_distance_t, long,
  310. property &lt; vertex_predecessor_t, Traits::edge_descriptor &gt; &gt; &gt; &gt; &gt;,
  311. property &lt; edge_capacity_t, long,
  312. property &lt; edge_residual_capacity_t, long,
  313. property &lt; edge_reverse_t, Traits::edge_descriptor &gt; &gt; &gt; &gt; Graph;
  314. Graph g;
  315. property_map &lt; Graph, edge_capacity_t &gt;::type
  316. capacity = get(edge_capacity, g);
  317. property_map &lt; Graph, edge_residual_capacity_t &gt;::type
  318. residual_capacity = get(edge_residual_capacity, g);
  319. property_map &lt; Graph, edge_reverse_t &gt;::type rev = get(edge_reverse, g);
  320. Traits::vertex_descriptor s, t;
  321. read_dimacs_max_flow(g, capacity, rev, s, t);
  322. std::vector&lt;default_color_type&gt; color(num_vertices(g));
  323. std::vector&lt;long&gt; distance(num_vertices(g));
  324. long flow = boykov_kolmogorov_max_flow(g ,s, t);
  325. std::cout &lt;&lt; "c The total flow:" &lt;&lt; std::endl;
  326. std::cout &lt;&lt; "s " &lt;&lt; flow &lt;&lt; std::endl &lt;&lt; std::endl;
  327. std::cout &lt;&lt; "c flow values:" &lt;&lt; std::endl;
  328. graph_traits &lt; Graph &gt;::vertex_iterator u_iter, u_end;
  329. graph_traits &lt; Graph &gt;::out_edge_iterator ei, e_end;
  330. for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
  331. for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
  332. if (capacity[*ei] &gt; 0)
  333. std::cout &lt;&lt; "f " &lt;&lt; *u_iter &lt;&lt; " " &lt;&lt; target(*ei, g) &lt;&lt; " "
  334. &lt;&lt; (capacity[*ei] - residual_capacity[*ei]) &lt;&lt; std::endl;
  335. return EXIT_SUCCESS;
  336. }</PRE><P>
  337. The output is:
  338. </P>
  339. <PRE>c The total flow:
  340. s 13
  341. c flow values:
  342. f 0 6 3
  343. f 0 1 0
  344. f 0 2 10
  345. f 1 5 1
  346. f 1 0 0
  347. f 1 3 0
  348. f 2 4 4
  349. f 2 3 6
  350. f 2 0 0
  351. f 3 7 5
  352. f 3 2 0
  353. f 3 1 1
  354. f 4 5 4
  355. f 4 6 0
  356. f 5 4 0
  357. f 5 7 5
  358. f 6 7 3
  359. f 6 4 0
  360. f 7 6 0
  361. f 7 5 0</PRE><H3>
  362. See Also</H3>
  363. <P STYLE="margin-bottom: 0cm">
  364. <TT><A HREF="edmonds_karp_max_flow.html">edmonds_karp_max_flow()</A></TT>,
  365. <TT><A HREF="push_relabel_max_flow.html">push_relabel_max_flow()</A></TT>.
  366. </P>
  367. <HR>
  368. <TABLE CELLPADDING=2 CELLSPACING=2>
  369. <TR VALIGN=TOP>
  370. <TD>
  371. <P>Copyright &copy; 2006</P>
  372. </TD>
  373. <TD>
  374. <P>Stephan Diederich, University
  375. Mannheim(<A HREF="mailto:diederich@ti.uni-manheim.de">diederich@ti.uni-manheim.de</A>)</P>
  376. </TD>
  377. </TR>
  378. </TABLE>
  379. <P><BR><BR>
  380. </P>
  381. </BODY>
  382. </HTML>