mcgregor_common_subgraphs.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
  2. <!--
  3. Copyright (c) Michael Hansen 2009
  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. <html>
  9. <head>
  10. <title>Boost Graph Library: McGregor Common Subgraphs</title>
  11. <style type="text/css">
  12. <!--
  13. body {
  14. color: black;
  15. background-color: white;
  16. }
  17. .comment {
  18. color: #333333;
  19. }
  20. a {
  21. color: blue;
  22. }
  23. a:visited {
  24. color: #551A8B;
  25. }
  26. -->
  27. </style>
  28. </head>
  29. <body>
  30. <img src="../../../boost.png" alt="C++ Boost" width="277" height="86" />
  31. <br />
  32. <h1>
  33. <tt>mcgregor_common_subgraphs</tt>
  34. </h1>
  35. <pre>
  36. <em class="comment">// named parameter version</em>
  37. template &lt;typename GraphFirst,
  38. typename GraphSecond,
  39. typename SubGraphCallback,
  40. typename Param,
  41. typename Tag,
  42. typename Rest&gt;
  43. void mcgregor_common_subgraphs
  44. (const GraphFirst&amp; graph1,
  45. const GraphSecond&amp; graph2,
  46. SubGraphCallback user_callback,
  47. bool only_connected_subgraphs,
  48. const bgl_named_params<Param, Tag, Rest>& params);
  49. <em class="comment">// non-named parameter version</em>
  50. template &lt;typename GraphFirst,
  51. typename GraphSecond,
  52. typename <a href="../../property_map/doc/ReadablePropertyMap.html">VertexIndexMapFirst</a>,
  53. typename <a href="../../property_map/doc/ReadablePropertyMap.html">VertexIndexMapSecond</a>,
  54. typename <a href="http://www.boost.org/sgi/stl/BinaryFunction.html">EdgeEquivalencePredicate</a>,
  55. typename <a href="http://www.boost.org/sgi/stl/BinaryFunction.html">VertexEquivalencePredicate</a>,
  56. typename SubGraphCallback&gt;
  57. void mcgregor_common_subgraphs
  58. (const GraphFirst&amp; graph1,
  59. const GraphSecond&amp; graph2,
  60. const VertexIndexMapFirst vindex_map1,
  61. const VertexIndexMapSecond vindex_map2,
  62. EdgeEquivalencePredicate edges_equivalent,
  63. VertexEquivalencePredicate vertices_equivalent,
  64. bool only_connected_subgraphs,
  65. SubGraphCallback user_callback);
  66. </pre>
  67. <p>
  68. This algorithm finds all common subgraphs
  69. between <tt>graph1</tt> and <tt>graph2</tt> and outputs them
  70. to <tt>user_callback</tt>. The <tt>edges_equivalent</tt>
  71. and <tt>vertices_equivalent</tt> predicates are used to
  72. determine edges and vertex equivalence between the two graphs.
  73. To use property maps for equivalence, look at
  74. the <tt><a href="#make_property_map_equivalent">make_property_map_equivalent</a></tt>
  75. function. By
  76. default, <tt><a href="#always_equivalent">always_equivalent</a></tt>
  77. is used, which returns true for any pair of edges or vertices.
  78. </p>
  79. <p>
  80. McGregor's algorithm does a depth-first search on the space of
  81. possible common subgraphs. At each level, every unvisited pair
  82. of vertices from <tt>graph1</tt> and <tt>graph2</tt> are checked
  83. to see if they can extend the current subgraph. This is done in
  84. three steps (assume <tt>vertex1</tt> is
  85. from <tt>graph1</tt> and <tt>vertex2</tt> is
  86. from <tt>graph2</tt>):
  87. <ol>
  88. <li>
  89. Verify that the <tt>vertex1</tt> and <tt>vertex2</tt> are
  90. equivalent using the <tt>vertices_equivalent</tt> predicate.
  91. </li>
  92. <li>
  93. For every vertex pair
  94. (<tt>existing_vertex1</tt>, <tt>existing_vertex2</tt>) in
  95. the current subgraph, ensure that any edges
  96. between <tt>vertex1</tt> and <tt>existing_vertex1</tt>
  97. in <tt>graph1</tt> and between <tt>vertex2</tt>
  98. and <tt>existing_vertex2</tt> in <tt>graph2</tt> match
  99. (i.e. either both exist of both don't exist). If both edges
  100. exist, they are checked for equivalence using
  101. the <tt>edges_equivalent</tt> predicate.
  102. </li>
  103. <li>
  104. Lastly (and optionally), make sure that the new subgraph
  105. vertex has at least one edge connecting it to the existing
  106. subgraph. When the <tt>only_connected_subgraphs</tt>
  107. parameter is false, this step is skipped.
  108. </li>
  109. </ol>
  110. </p>
  111. <h3>Where Defined</h3>
  112. <a href="../../../boost/graph/mcgregor_common_subgraphs.hpp"><tt>boost/graph/mcgregor_common_subgraphs.hpp</tt></a>
  113. <p>
  114. All functions are defined in the boost namespace.
  115. </p>
  116. <h3>Parameters</h3>
  117. IN: <tt>const GraphFirst&amp; graph1</tt>
  118. <blockquote>
  119. The first graph of the pair to be searched. The
  120. type <tt>GraphFirst</tt> must be a model of
  121. <a href="./VertexListGraph.html">Vertex List Graph</a>
  122. and <a href="./IncidenceGraph.html">Incidence Graph</a>. All
  123. parameters with a "<tt>1</tt>"
  124. (i.e. <tt>vindex_map1</tt>, <tt>correspondence_map_1_to_2</tt>)
  125. use this graph's vertices as keys.
  126. </blockquote>
  127. IN: <tt>const GraphSecond&amp; graph2</tt>
  128. <blockquote>
  129. The second graph of the pair to be searched. The
  130. type <tt>Graphsecond</tt> must be a model of
  131. <a href="./VertexListGraph.html">Vertex List Graph</a>
  132. and <a href="./IncidenceGraph.html">Incidence Graph</a>. All
  133. parameters with a "<tt>2</tt>"
  134. (i.e. <tt>vindex_map2</tt>, <tt>correspondence_map_2_to_1</tt>)
  135. use this graph's vertices as keys.
  136. </blockquote>
  137. IN: <tt>bool only_connected_subgraphs</tt>
  138. <blockquote>
  139. If <tt>true</tt>, subgraphs are expanded only when matching vertices
  140. have at least one edge connecting them to the existing subgraph.
  141. </blockquote>
  142. OUT: <tt>SubGraphCallback user_callback</tt>
  143. <blockquote>
  144. A function object that will be invoked when a subgraph has been discovered. The operator() must have the following form:
  145. <pre>
  146. template &lt;typename CorrespondenceMapFirstToSecond,
  147. typename CorrespondenceMapSecondToFirst&gt;
  148. bool operator()(CorrespondenceMapFirstToSecond correspondence_map_1_to_2,
  149. CorrespondenceMapSecondToFirst correspondence_map_2_to_1,
  150. typename graph_traits&lt;GraphFirst&gt;::vertices_size_type subgraph_size);
  151. </pre>
  152. Both the <tt>CorrespondenceMapFirstToSecond</tt>
  153. and <tt>CorresondenceMapSecondToFirst</tt> types are models
  154. of <a href="../../property_map/doc/ReadablePropertyMap.html">Readable
  155. Property Map</a> and map equivalent vertices across the two
  156. graphs given to <tt>mcgregor_common_subgraphs</tt>. For
  157. example, if <tt>vertex1</tt> is
  158. from <tt>graph1</tt>, <tt>vertex2</tt> is from <tt>graph2</tt>,
  159. and the vertices can be considered equivalent in the subgraph,
  160. then <tt>get(correspondence_map_1_to_2, vertex1)</tt> will
  161. be <tt>vertex2</tt> and <tt>get(correspondence_map_2_to_1,
  162. vertex2)</tt> will be <tt>vertex1</tt>. If any vertex,
  163. say <tt>vertex1</tt> in <tt>graph1</tt>, doesn't match a vertex
  164. in the other graph (<tt>graph2</tt> in this example),
  165. then <tt>get(correspondence_map_1_to_2, vertex1)</tt> will
  166. be <tt>graph_traits&lt;GraphSecond&gt;::null_vertex()</tt>.
  167. Likewise for any un-matched vertices from <tt>graph2</tt>,
  168. <tt>get(correspondence_map_2_to_1, vertex2)</tt> will
  169. be <tt>graph_traits&lt;GraphFirst&gt;::null_vertex()</tt>.
  170. <br /><br /> The <tt>subgraph_size</tt> parameter is the number
  171. of vertices in the subgraph, or the number of matched vertex
  172. pairs contained in the correspondence maps. This can be used to
  173. quickly filter out subgraphs whose sizes do not fall within the
  174. desired range.<br /><br />Returning <tt>false</tt> from the
  175. callback will abort the search immediately. Otherwise, the
  176. entire search space will be explored [<a href="#1">1</a>].
  177. </blockquote>
  178. <h3>Named Parameters</h3>
  179. IN: <tt>vertex_index1(VertexIndexMapFirst vindex_map1)</tt>
  180. <blockquote>
  181. This maps each vertex to an integer in the range <tt>[0,
  182. num_vertices(graph1)]</tt>. This is necessary for efficient storage
  183. of the subgraphs. The type VertexIndexMapFirst must be a model of
  184. <a href="../../property_map/doc/ReadablePropertyMap.html">Readable Property Map</a>.
  185. <br />
  186. <b>Default:</b> <tt>get(vertex_index, graph1)</tt>
  187. </blockquote>
  188. IN: <tt>vertex_index2(VertexIndexMapsecond vindex_map2)</tt>
  189. <blockquote>
  190. This maps each vertex to an integer in the range <tt>[0,
  191. num_vertices(graph2)]</tt>. This is necessary for efficient storage
  192. of the subgraphs. The type VertexIndexMapFirst must be a model of
  193. <a href="../../property_map/doc/ReadablePropertyMap.html">Readable Property Map</a>.
  194. <br />
  195. <b>Default:</b> <tt>get(vertex_index, graph2)</tt>
  196. </blockquote>
  197. IN: <tt>edges_equivalent(EdgeEquivalencePredicate edges_equivalent)</tt>
  198. <blockquote>
  199. This function is used to determine if edges
  200. between <tt>graph1</tt> and <tt>graph2</tt> are equivalent.
  201. The <tt>EdgeEquivalencePredicate</tt> type must be a model
  202. of <a href="http://www.boost.org/sgi/stl/BinaryPredicate.html">Binary
  203. Predicate</a> and have argument types
  204. of <tt>graph_traits&lt;GraphFirst&gt;::edge_descriptor</tt>
  205. and <tt>graph_traits&lt;GraphSecond&gt;::edge_descriptor</tt>.
  206. A return value of <tt>true</tt> indicates that the edges are
  207. equivalent. <br />
  208. <b>Default:</b> <tt><a href="#always_equivalent">always_equivalent</a></tt>
  209. </blockquote>
  210. IN: <tt>vertices_equivalent(VertexEquivalencePredicate vertices_equivalent)</tt>
  211. <blockquote>
  212. This function is used to determine if vertices
  213. between <tt>graph1</tt> and <tt>graph2</tt> are equivalent.
  214. The <tt>VertexEquivalencePredicate</tt> type must be a model
  215. of <a href="http://www.boost.org/sgi/stl/BinaryPredicate.html">Binary
  216. Predicate</a> and have argument types
  217. of <tt>graph_traits&lt;GraphFirst&gt;::vertex_descriptor</tt>
  218. and <tt>graph_traits&lt;GraphSecond&gt;::vertex_descriptor</tt>.
  219. A return value of <tt>true</tt> indicates that the vertices are
  220. equivalent.<br />
  221. <b>Default:</b> <tt><a href="#always_equivalent">always_equivalent</a></tt>
  222. </blockquote>
  223. <h3>Related Functions</h3>
  224. <p>
  225. Each <tt>mcgregor_common_subgraphs_*</tt> function below takes
  226. the same parameters as <tt>mcgregor_common_subgraphs</tt>.
  227. </p>
  228. <tt>mcgregor_common_subgraphs_unique(...);</tt>
  229. <blockquote>
  230. Keeps an internal cache of all discovered subgraphs and
  231. only invokes the <tt>user_callback</tt> for unique
  232. subgraphs. Returning <tt>false</tt>
  233. from <tt>user_callback</tt> will terminate the search as
  234. expected.
  235. </blockquote>
  236. <tt>mcgregor_common_subgraphs_maximum(...);</tt>
  237. <blockquote>
  238. Explores the <em>entire</em> search space and invokes
  239. the <tt>user_callback</tt> afterward with each of the largest
  240. discovered subgraphs. Returning <tt>false</tt> from
  241. the <tt>user_callback</tt> will <b>not</b> terminate the search
  242. because it is invoked after the search has been completed.
  243. </blockquote>
  244. <tt>mcgregor_common_subgraphs_maximum_unique(...);</tt>
  245. <blockquote>
  246. Explores the <em>entire</em> search space and invokes
  247. the <tt>user_callback</tt> afterward with each of the largest,
  248. unique discovered subgraphs. Returning <tt>false</tt> from
  249. the <tt>user_callback</tt> will <b>not</b> terminate the search
  250. because it is invoked after the search has been completed.
  251. </blockquote>
  252. <h3>Utility Functions/Structs</h3>
  253. <tt id="make_property_map_equivalent">
  254. property_map_equivalent&lt;PropertyMapFirst, PropertyMapSecond&gt;<br />
  255. &nbsp;&nbsp;make_property_map_equivalent(const PropertyMapFirst property_map1, const PropertyMapSecond property_map2);
  256. </tt>
  257. <blockquote>
  258. Returns a binary predicate function object
  259. (<tt>property_map_equivalent&lt;PropertyMapFirst,
  260. PropertyMapSecond&gt;</tt>) that compares vertices or edges
  261. between graphs using property maps. If, for
  262. example, <tt>vertex1</tt> and <tt>vertex2</tt> are the two
  263. parameters given when the function object is invoked,
  264. the <tt>operator()</tt> is effectively:
  265. <tt>return (get(m_property_map1, vertex1) == get(m_property_map2, vertex2));</tt>
  266. </blockquote>
  267. <tt id="always_equivalent">struct always_equivalent</tt>
  268. <blockquote>
  269. A binary function object that returns true for any pair of items.
  270. </blockquote>
  271. <tt>
  272. void fill_membership_map&lt;GraphSecond&gt;<br />
  273. (const GraphFirst& graph1, const CorrespondenceMapFirstToSecond correspondence_map_1_to_2, MembershipMapFirst membership_map1);
  274. </tt>
  275. <blockquote>
  276. Takes a subgraph (represented as a correspondence map) and fills
  277. the vertex membership map (vertex -> bool) (<tt>true</tt> means
  278. the vertex is present in the subgraph).
  279. <tt>MembershipMapFirst</tt> must
  280. model <a href="../../property_map/doc/WritablePropertyMap.html">Writable
  281. Property Map</a>.
  282. </blockquote>
  283. <tt>
  284. typename membership_filtered_graph_traits&lt;Graph, MembershipMap&gt;::graph_type<br />
  285. &nbsp;&nbsp;make_membership_filtered_graph(const Graph&amp; graph, MembershipMap&amp; membership_map);
  286. </tt>
  287. <blockquote>
  288. Creates a <a href="filtered_graph.html">Filtered Graph</a> from
  289. a subgraph, represented here as a vertex membership map (vertex
  290. -> bool where a value of <tt>true</tt> means that the vertex is
  291. present in the subgraph). All edges between the included
  292. vertices are preserved. See the example section for details.
  293. </blockquote>
  294. <h3>Complexity</h3>
  295. <p>
  296. The time complexity for searching the entire space is <em>O(V1 *
  297. V2)</em> where V1 is number of vertices in the first graph and
  298. V2 is the number of vertices in the second graph.
  299. </p>
  300. <h3>Examples</h3>
  301. <p>
  302. Before calling any of the <tt>mcregor_common_subgraphs</tt>
  303. algorithms, you must create a function object to act as a callback:
  304. </p>
  305. <pre>
  306. template &lt;typename GraphFirst,
  307. typename GraphSecond&gt;
  308. struct print_callback {
  309. print_callback(const GraphFirst&amp; graph1,
  310. const GraphSecond&amp; graph2) :
  311. m_graph1(graph1), m_graph2(graph2) { }
  312. template &lt;typename CorrespondenceMapFirstToSecond,
  313. typename CorrespondenceMapSecondToFirst&gt;
  314. bool operator()(CorrespondenceMapFirstToSecond correspondence_map_1_to_2,
  315. CorrespondenceMapSecondToFirst correspondence_map_2_to_1,
  316. typename graph_traits&lt;GraphFirst&gt;::vertices_size_type subgraph_size) {
  317. <em class="comment">// Print out correspondences between vertices</em>
  318. BGL_FORALL_VERTICES_T(vertex1, m_graph1, GraphFirst) {
  319. <em class="comment">// Skip unmapped vertices</em>
  320. if (get(correspondence_map_1_to_2, vertex1) != graph_traits&lt;GraphSecond&gt;::null_vertex()) {
  321. std::cout << vertex1 << " <-> " << get(correspondence_map_1_to_2, vertex1) << std::endl;
  322. }
  323. }
  324. std::cout << "---" << std::endl;
  325. return (true);
  326. }
  327. private:
  328. const GraphFirst&amp; m_graph1;
  329. const GraphSecond&amp; m_graph2;
  330. };
  331. <em class="comment">// Assuming the graph types GraphFirst and GraphSecond have already been defined</em>
  332. GraphFirst graph1;
  333. GraphSecond graph2;
  334. print_callback&lt;GraphFirst, GraphSecond&gt; my_callback(graph1, graph2);
  335. </pre>
  336. <h4>Example 1</h4>
  337. <p>
  338. If all the vertices and edges in your graph are identical, you
  339. can start enumerating subgraphs immediately:
  340. </p>
  341. <pre>
  342. <em class="comment">// Print out all connected common subgraphs between graph1 and graph2.
  343. // All vertices and edges are assumed to be equivalent and both graph1 and graph2
  344. // have implicit vertex index properties.</em>
  345. mcgregor_common_subgraphs(graph1, graph2, true, my_callback);
  346. </pre>
  347. <h4>Example 2</h4>
  348. <p>
  349. If the vertices and edges of your graphs can be differentiated
  350. with property maps, you can use
  351. the <tt>make_property_map_equivalent</tt> function to create a
  352. binary predicate for vertex or edge equivalence:
  353. </p>
  354. <pre>
  355. <em class="comment">// Assume both graphs were defined with implicit vertex name,
  356. // edge name, and vertex index properties</em>
  357. property_map&lt;GraphFirst, vertex_name_t&gt; vname_map1 = get(vertex_name, graph1);
  358. property_map&lt;GraphSecond, vertex_name_t&gt; vname_map1 = get(vertex_name, graph2);
  359. property_map&lt;GraphFirst, edge_name_t&gt; ename_map1 = get(edge_name, graph1);
  360. property_map&lt;GraphSecond, edge_name_t&gt; ename_map1 = get(edge_name, graph2);
  361. <em class="comment">// Print out all connected common subgraphs between graph1 and graph2.</em>
  362. mcgregor_common_subgraphs(graph1, graph2, true, my_callback,
  363. edges_equivalent(make_property_map_equivalent(ename_map1, ename_map2)).
  364. vertices_equivalent(make_property_map_equivalent(vname_map1, vname_map2)));
  365. </pre>
  366. <h4>Example 3</h4>
  367. <p>
  368. There are some helper functions that can be used to obtain a
  369. filtered graph from the correspondence maps given in your
  370. callback:
  371. </p>
  372. <pre>
  373. <em class="comment">// Assuming we're inside the operator() of the callback with a member variable m_graph1 representing the first graph passed to mcgregor_common_subgraphs.
  374. // ...</em>
  375. <em class="comment">// Step 1: Transform a correspondence map into a membership map. Any vertex -> bool property map will work</em>
  376. typedef shared_array_property_map<bool, VertexIndexMap> MembershipMap;
  377. MembershipMap membership_map1(num_vertices(m_graph1), get(vertex_index, m_graph1));
  378. <em class="comment">// Fill the membership map for m_graph1. GraphSecond is the type of the second graph given to mcgregor_common_subgraphs.</em>
  379. fill_membership_map&lt;GraphSecond&gt;(m_graph1, correspondence_map_1_to_2, membership_map1);
  380. <em class="comment">// Step 2: Use the membership map from Step 1 to obtain a filtered graph</em>
  381. typedef typename membership_filtered_graph_traits&lt;GraphFirst, MembershipMap&gt;::graph_type
  382. MembershipFilteredGraph;
  383. MembershipFilteredGraph subgraph1 = make_membership_filtered_graph(m_graph1, membership_map1);
  384. <em class="comment">// The filtered graph can be used like a regular BGL graph...</em>
  385. BGL_FORALL_VERTICES_T(vertex1, subgraph1, MembershipFilteredGraph) {
  386. std::cout << vertex1 << " is present in the subgraph of graph1" << std::endl;
  387. }
  388. </pre>
  389. <h3>Notes</h3>
  390. <p>
  391. <a name="1">[1]</a>
  392. For <tt>mcgregor_common_subgraphs_maximum</tt>
  393. and <tt>mcgregor_common_subgraphs_maximum_unique</tt> the entire
  394. search space is always explored, so the return value of the
  395. callback has no effect.
  396. </p>
  397. <hr />
  398. Copyright &copy; 2009 Trustees of Indiana University
  399. </body>
  400. </html>