transitive_closure.html 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <HTML>
  2. <!--
  3. Copyright (c) Jeremy Siek 2001
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. -->
  8. <Head>
  9. <Title>Boost Graph Library: Transitive Closure</Title>
  10. <BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
  11. ALINK="#ff0000">
  12. <IMG SRC="../../../boost.png"
  13. ALT="C++ Boost" width="277" height="86">
  14. <BR Clear>
  15. <H1><A NAME="sec:transitive_closure">
  16. <img src="figs/python.gif" alt="(Python)"/>
  17. <TT>transitive_closure</TT>
  18. </H1>
  19. <P>
  20. <PRE>
  21. template &lt;typename Graph, typename GraphTC,
  22. typename P, typename T, typename R&gt;
  23. void transitive_closure(const Graph&amp; g, GraphTC&amp; tc,
  24. const bgl_named_params&lt;P, T, R&gt;&amp; params = <i>all defaults</i>)
  25. template &lt;typename Graph, typename GraphTC,
  26. typename G_to_TC_VertexMap, typename VertexIndexMap&gt;
  27. void transitive_closure(const Graph&amp; g, GraphTC&amp; tc,
  28. G_to_TC_VertexMap g_to_tc_map, VertexIndexMap index_map)
  29. </PRE>
  30. The transitive closure of a graph <i>G = (V,E)</i> is a graph <i>G* =
  31. (V,E*)</i> such that <i>E*</i> contains an edge <i>(u,v)</i> if and
  32. only if <i>G</i> contains a <a
  33. href="graph_theory_review.html#def:path">path</a> (of at least one
  34. edge) from <i>u</i> to <i>v</i>. The <tt>transitive_closure()</tt>
  35. function transforms the input graph <tt>g</tt> into the transitive
  36. closure graph <tt>tc</tt>.
  37. <p>
  38. Thanks to Vladimir Prus for the implementation of this algorithm!
  39. <H3>Where Defined</H3>
  40. <P>
  41. <a href="../../../boost/graph/transitive_closure.hpp"><TT>boost/graph/transitive_closure.hpp</TT></a>
  42. <h3>Parameters</h3>
  43. IN: <tt>const Graph&amp; g</tt>
  44. <blockquote>
  45. A directed graph, where the <tt>Graph</tt> type must model the
  46. <a href="./VertexListGraph.html">Vertex List Graph</a>,
  47. <a href="./AdjacencyGraph.html">Adjacency Graph</a>,
  48. and <a href="./AdjacencyMatrix.html">Adjacency Matrix</a> concepts.<br>
  49. <b>Python</b>: The parameter is named <tt>graph</tt>.
  50. </blockquote>
  51. OUT: <tt>GraphTC&amp; tc</tt>
  52. <blockquote>
  53. A directed graph, where the <tt>GraphTC</tt> type must model the
  54. <a href="./VertexMutableGraph.html">Vertex Mutable Graph</a>
  55. and <a href="./EdgeMutableGraph.html">Edge Mutable Graph</a> concepts.<br>
  56. <b>Python</b>: This parameter is not used in Python. Instead, a new
  57. graph of the same type is returned.
  58. </blockquote>
  59. <h3>Named Parameters</h3>
  60. UTIL/OUT: <tt>orig_to_copy(G_to_TC_VertexMap g_to_tc_map)</tt>
  61. <blockquote>
  62. This maps each vertex in the input graph to the new matching
  63. vertices in the output transitive closure graph.<br>
  64. <b>Python</b>: This must be a <tt>vertex_vertex_map</tt> of the graph.
  65. </blockquote>
  66. IN: <tt>vertex_index_map(VertexIndexMap&amp; index_map)</tt>
  67. <blockquote>
  68. This maps each vertex to an integer in the range <tt>[0,
  69. num_vertices(g))</tt>. This parameter is only necessary when the
  70. default color property map is used. The type <tt>VertexIndexMap</tt>
  71. must be a model of <a
  72. href="../../property_map/doc/ReadablePropertyMap.html">Readable Property
  73. Map</a>. The value type of the map must be an integer type. The
  74. vertex descriptor type of the graph needs to be usable as the key
  75. type of the map.<br>
  76. <b>Default:</b> <tt>get(vertex_index, g)</tt>
  77. Note: if you use this default, make sure your graph has
  78. an internal <tt>vertex_index</tt> property. For example,
  79. <tt>adjacency_list</tt> with <tt>VertexList=listS</tt> does
  80. not have an internal <tt>vertex_index</tt> property.
  81. <br>
  82. <b>Python</b>: Unsupported parameter.
  83. </blockquote>
  84. <h3>Complexity</h3>
  85. The time complexity (worst-case) is <i>O(|V||E|)</i>.
  86. <h3>Example</h3>
  87. The following is the graph from the example <tt><a
  88. href="../example/transitive_closure.cpp">example/transitive_closure.cpp</a></tt>
  89. and the transitive closure computed by the algorithm.
  90. <table>
  91. <tr>
  92. <td><img src="tc.gif" width="173" height="264" ></td>
  93. <td><img src="tc-out.gif" width="200" height="360"></td>
  94. </tr>
  95. </table>
  96. <h3>Implementation Notes</h3>
  97. <p>
  98. The algorithm used to implement the <tt>transitive_closure()</tt>
  99. function is based on the detection of strong components[<a
  100. href="bibliography.html#nuutila95">50</a>, <a
  101. href="bibliography.html#purdom70">53</a>]. The following discussion
  102. describes the algorithm (and some relevant background theory).
  103. <p>
  104. A <a name="def:successor-set"><i><b>successor set</b></i></a> of a
  105. vertex <i>v</i>, denoted by <i>Succ(v)</i>, is the set of vertices
  106. that are <a
  107. href="graph_theory_review.html#def:reachable">reachable</a> from
  108. vertex <i>v</i>. The set of vertices adjacent to <i>v</i> in the
  109. transitive closure <i>G*</i> is the same as the successor set of
  110. <i>v</i> in the original graph <i>G</i>. Computing the transitive
  111. closure is equivalent to computing the successor set for every vertex
  112. in <i>G</i>.
  113. <p>
  114. All vertices in the same strong component have the same successor set
  115. (because every vertex is reachable from all the other vertices in the
  116. component). Therefore, it is redundant to compute the successor set
  117. for every vertex in a strong component; it suffices to compute it for
  118. just one vertex per component.
  119. <p>
  120. The following is the outline of the algorithm:
  121. <ol>
  122. <li>Compute <a
  123. href="strong_components.html#def:strongly-connected-component">strongly
  124. connected components</a> of the graph.
  125. <li> Construct the condensation graph. A <a
  126. name="def:condensation-graph"><i><b>condensation graph</b></i></a> is
  127. a a graph <i>G'=(V',E')</i> based on the graph <i>G=(V,E)</i> where
  128. each vertex in <i>V'</i> corresponds to a strongly connected component
  129. in <i>G</i> and edge <i>(u,v)</i> is in <i>E'</i> if and only if there
  130. exists an edge in <i>E</i> connecting any of the vertices in the
  131. component of <i>u</i> to any of the vertices in the component of
  132. <i>v</i>.
  133. <li> Compute transitive closure on the condensation graph.
  134. This is done using the following algorithm:
  135. <pre>
  136. for each vertex u in G' in reverse topological order
  137. for each vertex v in Adj[u]
  138. if (v not in Succ(u))
  139. Succ(u) = Succ(u) U { v } U Succ(v) // &quot;U&quot; means set union
  140. </pre>
  141. The vertices are considered in reverse topological order to
  142. ensure that the when computing the successor set for a vertex
  143. <i>u</i>, the successor set for each vertex in <i>Adj[u]</i>
  144. has already been computed.
  145. <p>An optimized implementation of the set union operation improves
  146. the performance of the algorithm. Therefore this implementation
  147. uses <a name="def:chain-decomposition"><i><b>chain
  148. decomposition</b></i></a> [<a
  149. href="bibliography.html#goral79">51</a>,<a
  150. href="bibliography.html#simon86">52</a>]. The vertices of <i>G</i>
  151. are partitioned into chains <i>Z<sub>1</sub>, ...,
  152. Z<sub>k</sub></i>, where each chain <i>Z<sub>i</sub></i> is a path
  153. in <i>G</i> and the vertices in a chain have increasing topological
  154. number. A successor set <i>S</i> is then represented by a
  155. collection of intersections with the chains, i.e., <i>S =
  156. U<sub>i=1...k</sub> (Z<sub>i</sub> &amp; S)</i>. Each intersection
  157. can be represented by the first vertex in the path
  158. <i>Z<sub>i</sub></i> that is also in <i>S</I>, since the rest of
  159. the path is guaranteed to also be in <i>S</i>. The collection of
  160. intersections is therefore represented by a vector of length
  161. <i>k</i> where the ith element of the vector stores the first
  162. vertex in the intersection of <i>S</i> with <i>Z<sub>i</sub></i>.
  163. <p>Computing the union of two successor sets, <i>S<sub>3</sub> =
  164. S<sub>1</sub> U S<sub>2</sub></i>, can then be computed in
  165. <i>O(k)</i> time with the following operation:
  166. <pre>
  167. for i = 0...k
  168. S3[i] = min(S1[i], S2[i]) // where min compares the topological number of the vertices
  169. </pre>
  170. <li>Create the graph <i>G*</i> based on the transitive closure of
  171. the condensation graph <i>G'*</i>.
  172. </ol>
  173. <br>
  174. <HR>
  175. <TABLE>
  176. <TR valign=top>
  177. <TD nowrap>Copyright &copy; 2001</TD><TD>
  178. <A HREF="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</A>, Indiana Univ.(<A HREF="mailto:jsiek@cs.indiana.edu">jsiek@cs.indiana.edu</A>)
  179. </TD></TR></TABLE>
  180. </BODY>
  181. </HTML>