basic_planarity_test.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. //=======================================================================
  2. // Copyright 2007 Aaron Windsor
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //=======================================================================
  8. #include <boost/graph/adjacency_list.hpp>
  9. #include <boost/graph/properties.hpp>
  10. #include <boost/graph/boyer_myrvold_planar_test.hpp>
  11. #include <boost/property_map/property_map.hpp>
  12. #include <boost/property_map/vector_property_map.hpp>
  13. #include <boost/test/minimal.hpp>
  14. using namespace boost;
  15. struct VertexIndexUpdater
  16. {
  17. template <typename Graph>
  18. void reset(Graph& g)
  19. {
  20. typename property_map<Graph, vertex_index_t>::type index = get(vertex_index, g);
  21. typename graph_traits<Graph>::vertex_iterator vi, vi_end;
  22. typename graph_traits<Graph>::vertices_size_type cnt = 0;
  23. for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
  24. put(index, *vi, cnt++);
  25. }
  26. };
  27. struct NoVertexIndexUpdater
  28. {
  29. template <typename Graph> void reset(Graph&) {}
  30. };
  31. template <typename Graph, typename VertexIndexUpdater>
  32. void test_K_5(VertexIndexUpdater vertex_index)
  33. {
  34. typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
  35. Graph g;
  36. vertex_t v1 = add_vertex(g);
  37. vertex_t v2 = add_vertex(g);
  38. vertex_t v3 = add_vertex(g);
  39. vertex_t v4 = add_vertex(g);
  40. vertex_t v5 = add_vertex(g);
  41. vertex_index.reset(g);
  42. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  43. add_edge(v1, v2, g);
  44. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  45. add_edge(v1, v3, g);
  46. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  47. add_edge(v1, v4, g);
  48. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  49. add_edge(v1, v5, g);
  50. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  51. add_edge(v2, v3, g);
  52. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  53. add_edge(v2, v4, g);
  54. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  55. add_edge(v2, v5, g);
  56. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  57. add_edge(v3, v4, g);
  58. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  59. add_edge(v3, v5, g);
  60. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  61. //This edge should make the graph non-planar
  62. add_edge(v4, v5, g);
  63. BOOST_CHECK(!boyer_myrvold_planarity_test(g));
  64. }
  65. template <typename Graph, typename VertexIndexUpdater>
  66. void test_K_3_3(VertexIndexUpdater vertex_index)
  67. {
  68. typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
  69. Graph g;
  70. vertex_t v1 = add_vertex(g);
  71. vertex_t v2 = add_vertex(g);
  72. vertex_t v3 = add_vertex(g);
  73. vertex_t v4 = add_vertex(g);
  74. vertex_t v5 = add_vertex(g);
  75. vertex_t v6 = add_vertex(g);
  76. vertex_index.reset(g);
  77. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  78. add_edge(v1, v4, g);
  79. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  80. add_edge(v1, v5, g);
  81. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  82. add_edge(v1, v6, g);
  83. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  84. add_edge(v2, v4, g);
  85. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  86. add_edge(v2, v5, g);
  87. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  88. add_edge(v2, v6, g);
  89. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  90. add_edge(v3, v4, g);
  91. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  92. add_edge(v3, v5, g);
  93. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  94. //This edge should make the graph non-planar
  95. add_edge(v3, v6, g);
  96. BOOST_CHECK(!boyer_myrvold_planarity_test(g));
  97. }
  98. // This test creates a maximal planar graph on num_vertices vertices,
  99. // then, if num_vertices is at least 5, adds an additional edge to
  100. // create a non-planar graph.
  101. template <typename Graph, typename VertexIndexUpdater>
  102. void test_maximal_planar(VertexIndexUpdater vertex_index, std::size_t num_vertices)
  103. {
  104. typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
  105. Graph g;
  106. std::vector<vertex_t> vmap;
  107. for(std::size_t i = 0; i < num_vertices; ++i)
  108. vmap.push_back(add_vertex(g));
  109. vertex_index.reset(g);
  110. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  111. //create a cycle
  112. for(std::size_t i = 0; i < num_vertices; ++i)
  113. {
  114. add_edge(vmap[i], vmap[(i+1) % num_vertices], g);
  115. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  116. }
  117. //triangulate the interior of the cycle.
  118. for(std::size_t i = 2; i < num_vertices - 1; ++i)
  119. {
  120. add_edge(vmap[0], vmap[i], g);
  121. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  122. }
  123. //triangulate the exterior of the cycle.
  124. for(std::size_t i = 3; i < num_vertices; ++i)
  125. {
  126. add_edge(vmap[1], vmap[i], g);
  127. BOOST_CHECK(boyer_myrvold_planarity_test(g));
  128. }
  129. //Now add an additional edge, forcing the graph to be non-planar.
  130. if (num_vertices > 4)
  131. {
  132. add_edge(vmap[2], vmap[4], g);
  133. BOOST_CHECK(!boyer_myrvold_planarity_test(g));
  134. }
  135. }
  136. int test_main(int, char* [])
  137. {
  138. typedef adjacency_list
  139. <vecS,
  140. vecS,
  141. undirectedS,
  142. property<vertex_index_t, int>
  143. >
  144. VVgraph_t;
  145. typedef adjacency_list
  146. <vecS,
  147. listS,
  148. undirectedS,
  149. property<vertex_index_t, int>
  150. >
  151. VLgraph_t;
  152. typedef adjacency_list
  153. <listS,
  154. vecS,
  155. undirectedS,
  156. property<vertex_index_t, int>
  157. >
  158. LVgraph_t;
  159. typedef adjacency_list
  160. <listS,
  161. listS,
  162. undirectedS,
  163. property<vertex_index_t, int>
  164. >
  165. LLgraph_t;
  166. typedef adjacency_list
  167. <setS,
  168. setS,
  169. undirectedS,
  170. property<vertex_index_t, int>
  171. >
  172. SSgraph_t;
  173. test_K_5<VVgraph_t>(NoVertexIndexUpdater());
  174. test_K_3_3<VVgraph_t>(NoVertexIndexUpdater());
  175. test_maximal_planar<VVgraph_t>(NoVertexIndexUpdater(), 3);
  176. test_maximal_planar<VVgraph_t>(NoVertexIndexUpdater(), 6);
  177. test_maximal_planar<VVgraph_t>(NoVertexIndexUpdater(), 10);
  178. test_maximal_planar<VVgraph_t>(NoVertexIndexUpdater(), 20);
  179. test_maximal_planar<VVgraph_t>(NoVertexIndexUpdater(), 50);
  180. test_K_5<VLgraph_t>(VertexIndexUpdater());
  181. test_K_3_3<VLgraph_t>(VertexIndexUpdater());
  182. test_maximal_planar<VLgraph_t>(VertexIndexUpdater(), 3);
  183. test_maximal_planar<VLgraph_t>(VertexIndexUpdater(), 6);
  184. test_maximal_planar<VLgraph_t>(VertexIndexUpdater(), 10);
  185. test_maximal_planar<VLgraph_t>(VertexIndexUpdater(), 20);
  186. test_maximal_planar<VLgraph_t>(VertexIndexUpdater(), 50);
  187. test_K_5<LVgraph_t>(NoVertexIndexUpdater());
  188. test_K_3_3<LVgraph_t>(NoVertexIndexUpdater());
  189. test_maximal_planar<LVgraph_t>(NoVertexIndexUpdater(), 3);
  190. test_maximal_planar<LVgraph_t>(NoVertexIndexUpdater(), 6);
  191. test_maximal_planar<LVgraph_t>(NoVertexIndexUpdater(), 10);
  192. test_maximal_planar<LVgraph_t>(NoVertexIndexUpdater(), 20);
  193. test_maximal_planar<LVgraph_t>(NoVertexIndexUpdater(), 50);
  194. test_K_5<LLgraph_t>(VertexIndexUpdater());
  195. test_K_3_3<LLgraph_t>(VertexIndexUpdater());
  196. test_maximal_planar<LLgraph_t>(VertexIndexUpdater(), 3);
  197. test_maximal_planar<LLgraph_t>(VertexIndexUpdater(), 6);
  198. test_maximal_planar<LLgraph_t>(VertexIndexUpdater(), 10);
  199. test_maximal_planar<LLgraph_t>(VertexIndexUpdater(), 20);
  200. test_maximal_planar<LLgraph_t>(VertexIndexUpdater(), 50);
  201. test_K_5<SSgraph_t>(VertexIndexUpdater());
  202. test_K_3_3<SSgraph_t>(VertexIndexUpdater());
  203. test_maximal_planar<SSgraph_t>(VertexIndexUpdater(), 3);
  204. test_maximal_planar<SSgraph_t>(VertexIndexUpdater(), 6);
  205. test_maximal_planar<SSgraph_t>(VertexIndexUpdater(), 10);
  206. test_maximal_planar<SSgraph_t>(VertexIndexUpdater(), 20);
  207. test_maximal_planar<SSgraph_t>(VertexIndexUpdater(), 50);
  208. return 0;
  209. }