vf2_sub_graph_iso_test_2.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. //=======================================================================
  2. // Boost.Graph library vf2_sub_graph_iso test 2
  3. // Test of return value and behaviour with empty graphs
  4. //
  5. // Copyright (C) 2013 Jakob Lykke Andersen, University of Southern Denmark (jlandersen@imada.sdu.dk)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See
  8. // accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //=======================================================================
  11. #include <iostream>
  12. #include <boost/test/minimal.hpp>
  13. #include <boost/graph/adjacency_list.hpp>
  14. #include <boost/graph/vf2_sub_graph_iso.hpp>
  15. struct test_callback {
  16. test_callback(bool &got_hit, bool stop) : got_hit(got_hit), stop(stop) { }
  17. template<typename Map1To2, typename Map2To1>
  18. bool operator()(Map1To2 map1to2, Map2To1 map2to1) {
  19. got_hit = true;
  20. return stop;
  21. }
  22. bool &got_hit;
  23. bool stop;
  24. };
  25. struct false_predicate {
  26. template<typename VertexOrEdge1, typename VertexOrEdge2>
  27. bool operator()(VertexOrEdge1 ve1, VertexOrEdge2 ve2) const {
  28. return false;
  29. }
  30. };
  31. void test_empty_graph_cases() {
  32. typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> Graph;
  33. Graph gEmpty, gLarge;
  34. add_vertex(gLarge);
  35. { // isomorphism
  36. bool got_hit = false;
  37. test_callback callback(got_hit, true);
  38. bool exists = vf2_graph_iso(gEmpty, gEmpty, callback);
  39. BOOST_CHECK(exists);
  40. BOOST_CHECK(got_hit); // even empty matches are reported
  41. }
  42. { // subgraph isomorphism (induced)
  43. { // empty vs. empty
  44. bool got_hit = false;
  45. test_callback callback(got_hit, true);
  46. bool exists = vf2_subgraph_iso(gEmpty, gEmpty, callback);
  47. BOOST_CHECK(exists);
  48. BOOST_CHECK(got_hit); // even empty matches are reported
  49. }
  50. { // empty vs. non-empty
  51. bool got_hit = false;
  52. test_callback callback(got_hit, true);
  53. bool exists = vf2_subgraph_iso(gEmpty, gLarge, callback);
  54. BOOST_CHECK(exists);
  55. BOOST_CHECK(got_hit); // even empty matches are reported
  56. }
  57. }
  58. { // subgraph monomorphism (non-induced subgraph isomorphism)
  59. { // empty vs. empty
  60. bool got_hit = false;
  61. test_callback callback(got_hit, true);
  62. bool exists = vf2_subgraph_mono(gEmpty, gEmpty, callback);
  63. BOOST_CHECK(exists);
  64. BOOST_CHECK(got_hit); // even empty matches are reported
  65. }
  66. { // empty vs. non-empty
  67. bool got_hit = false;
  68. test_callback callback(got_hit, true);
  69. bool exists = vf2_subgraph_mono(gEmpty, gLarge, callback);
  70. BOOST_CHECK(exists);
  71. BOOST_CHECK(got_hit); // even empty matches are reported
  72. }
  73. }
  74. }
  75. void test_return_value() {
  76. typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> Graph;
  77. typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
  78. Graph gSmall, gLarge;
  79. add_vertex(gSmall);
  80. Vertex v1 = add_vertex(gLarge);
  81. Vertex v2 = add_vertex(gLarge);
  82. add_edge(v1, v2, gLarge);
  83. { // isomorphism
  84. { // no morphism due to sizes
  85. bool got_hit = false;
  86. test_callback callback(got_hit, true);
  87. bool exists = vf2_graph_iso(gSmall, gLarge, callback);
  88. BOOST_CHECK(!exists);
  89. BOOST_CHECK(!got_hit);
  90. }
  91. { // no morphism due to vertex mismatches
  92. bool got_hit = false;
  93. test_callback callback(got_hit, true);
  94. false_predicate pred;
  95. bool exists = vf2_graph_iso(gLarge, gLarge, callback, vertex_order_by_mult(gLarge),
  96. boost::edges_equivalent(pred).vertices_equivalent(pred));
  97. BOOST_CHECK(!exists);
  98. BOOST_CHECK(!got_hit);
  99. }
  100. { // morphism, find all
  101. bool got_hit = false;
  102. test_callback callback(got_hit, false);
  103. bool exists = vf2_graph_iso(gLarge, gLarge, callback);
  104. BOOST_CHECK(exists);
  105. BOOST_CHECK(got_hit);
  106. }
  107. { // morphism, stop after first hit
  108. bool got_hit = false;
  109. test_callback callback(got_hit, true);
  110. bool exists = vf2_graph_iso(gLarge, gLarge, callback);
  111. BOOST_CHECK(exists);
  112. BOOST_CHECK(got_hit);
  113. }
  114. }
  115. { // subgraph isomorphism (induced)
  116. { // no morphism due to sizes
  117. bool got_hit = false;
  118. test_callback callback(got_hit, true);
  119. bool exists = vf2_subgraph_iso(gLarge, gSmall, callback);
  120. BOOST_CHECK(!exists);
  121. BOOST_CHECK(!got_hit);
  122. }
  123. { // no morphism due to vertex mismatches
  124. bool got_hit = false;
  125. test_callback callback(got_hit, true);
  126. false_predicate pred;
  127. bool exists = vf2_subgraph_iso(gLarge, gLarge, callback, vertex_order_by_mult(gLarge),
  128. boost::edges_equivalent(pred).vertices_equivalent(pred));
  129. BOOST_CHECK(!exists);
  130. BOOST_CHECK(!got_hit);
  131. }
  132. { // morphism, find all
  133. bool got_hit = false;
  134. test_callback callback(got_hit, false);
  135. bool exists = vf2_subgraph_iso(gLarge, gLarge, callback);
  136. BOOST_CHECK(exists);
  137. BOOST_CHECK(got_hit);
  138. }
  139. { // morphism, stop after first hit
  140. bool got_hit = false;
  141. test_callback callback(got_hit, true);
  142. bool exists = vf2_subgraph_iso(gLarge, gLarge, callback);
  143. BOOST_CHECK(exists);
  144. BOOST_CHECK(got_hit);
  145. }
  146. }
  147. { // subgraph monomorphism (non-induced subgraph isomorphism)
  148. { // no morphism due to sizes
  149. bool got_hit = false;
  150. test_callback callback(got_hit, true);
  151. bool exists = vf2_subgraph_mono(gLarge, gSmall, callback);
  152. BOOST_CHECK(!exists);
  153. BOOST_CHECK(!got_hit);
  154. }
  155. { // no morphism due to vertex mismatches
  156. bool got_hit = false;
  157. test_callback callback(got_hit, true);
  158. false_predicate pred;
  159. bool exists = vf2_subgraph_mono(gLarge, gLarge, callback, vertex_order_by_mult(gLarge),
  160. boost::edges_equivalent(pred).vertices_equivalent(pred));
  161. BOOST_CHECK(!exists);
  162. BOOST_CHECK(!got_hit);
  163. }
  164. { // morphism, find all
  165. bool got_hit = false;
  166. test_callback callback(got_hit, false);
  167. bool exists = vf2_subgraph_mono(gLarge, gLarge, callback);
  168. BOOST_CHECK(exists);
  169. BOOST_CHECK(got_hit);
  170. }
  171. { // morphism, stop after first hit
  172. bool got_hit = false;
  173. test_callback callback(got_hit, true);
  174. bool exists = vf2_subgraph_mono(gLarge, gLarge, callback);
  175. BOOST_CHECK(exists);
  176. BOOST_CHECK(got_hit);
  177. }
  178. }
  179. }
  180. int test_main(int argc, char* argv[]) {
  181. test_empty_graph_cases();
  182. test_return_value();
  183. return 0;
  184. }