make_connected_test.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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/make_connected.hpp>
  11. #include <boost/graph/connected_components.hpp>
  12. #include <boost/property_map/property_map.hpp>
  13. #include <boost/property_map/vector_property_map.hpp>
  14. #include <boost/test/minimal.hpp>
  15. using namespace boost;
  16. template <typename Graph>
  17. void reset_edge_index(Graph& g)
  18. {
  19. typename property_map<Graph, edge_index_t>::type index = get(edge_index, g);
  20. typename graph_traits<Graph>::edge_iterator ei, ei_end;
  21. typename graph_traits<Graph>::edges_size_type cnt = 0;
  22. for(boost::tie(ei,ei_end) = edges(g); ei != ei_end; ++ei)
  23. put(index, *ei, cnt++);
  24. }
  25. template <typename Graph>
  26. void reset_vertex_index(Graph& g)
  27. {
  28. typename property_map<Graph, vertex_index_t>::type index = get(vertex_index, g);
  29. typename graph_traits<Graph>::vertex_iterator vi, vi_end;
  30. typename graph_traits<Graph>::vertices_size_type cnt = 0;
  31. for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
  32. put(index, *vi, cnt++);
  33. }
  34. template <typename Graph>
  35. void make_disconnected_cycles(Graph& g, int num_cycles, int cycle_size)
  36. {
  37. // This graph will consist of num_cycles cycles, each of which
  38. // has cycle_size vertices and edges. The entire graph has
  39. // num_cycles * cycle_size vertices and edges, and requires
  40. // num_cycles - 1 edges to make it connected
  41. typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
  42. for(int i = 0; i < num_cycles; ++i)
  43. {
  44. vertex_t first_vertex = add_vertex(g);
  45. vertex_t prev_vertex;
  46. vertex_t curr_vertex = first_vertex;
  47. for(int j = 1; j < cycle_size; ++j)
  48. {
  49. prev_vertex = curr_vertex;
  50. curr_vertex = add_vertex(g);
  51. add_edge(prev_vertex, curr_vertex, g);
  52. }
  53. add_edge(curr_vertex, first_vertex, g);
  54. }
  55. }
  56. int test_main(int, char* [])
  57. {
  58. typedef adjacency_list
  59. <vecS,
  60. vecS,
  61. undirectedS,
  62. property<vertex_index_t, int>,
  63. property<edge_index_t, int>
  64. >
  65. VVgraph_t;
  66. typedef adjacency_list
  67. <vecS,
  68. listS,
  69. undirectedS,
  70. property<vertex_index_t, int>,
  71. property<edge_index_t, int>
  72. >
  73. VLgraph_t;
  74. typedef adjacency_list
  75. <listS,
  76. vecS,
  77. undirectedS,
  78. property<vertex_index_t, int>,
  79. property<edge_index_t, int>
  80. >
  81. LVgraph_t;
  82. typedef adjacency_list
  83. <listS,
  84. listS,
  85. undirectedS,
  86. property<vertex_index_t, int>,
  87. property<edge_index_t, int>
  88. >
  89. LLgraph_t;
  90. VVgraph_t gVV;
  91. std::size_t num_cycles = 10;
  92. std::size_t cycle_size = 10;
  93. make_disconnected_cycles(gVV, num_cycles, cycle_size);
  94. reset_edge_index(gVV);
  95. std::vector<int> gVV_components(num_vertices(gVV));
  96. boost::iterator_property_map<
  97. std::vector<int>::iterator,
  98. boost::property_map<VVgraph_t, boost::vertex_index_t>::const_type
  99. > gVV_components_pm(gVV_components.begin(), get(boost::vertex_index, gVV));
  100. BOOST_CHECK(connected_components(gVV, gVV_components_pm) ==
  101. static_cast<int>(num_cycles));
  102. make_connected(gVV);
  103. BOOST_CHECK(connected_components(gVV, gVV_components_pm) == 1);
  104. BOOST_CHECK(num_edges(gVV) == num_cycles * cycle_size + num_cycles - 1);
  105. LVgraph_t gLV;
  106. num_cycles = 20;
  107. cycle_size = 20;
  108. make_disconnected_cycles(gLV, num_cycles, cycle_size);
  109. reset_edge_index(gLV);
  110. std::vector<int> gLV_components(num_vertices(gLV));
  111. boost::iterator_property_map<
  112. std::vector<int>::iterator,
  113. boost::property_map<VVgraph_t, boost::vertex_index_t>::const_type
  114. > gLV_components_pm(gLV_components.begin(), get(boost::vertex_index, gLV));
  115. BOOST_CHECK(connected_components(gLV, gLV_components_pm) ==
  116. static_cast<int>(num_cycles));
  117. make_connected(gLV);
  118. BOOST_CHECK(connected_components(gLV, gLV_components_pm) == 1);
  119. BOOST_CHECK(num_edges(gLV) == num_cycles * cycle_size + num_cycles - 1);
  120. VLgraph_t gVL;
  121. num_cycles = 30;
  122. cycle_size = 30;
  123. make_disconnected_cycles(gVL, num_cycles, cycle_size);
  124. reset_edge_index(gVL);
  125. reset_vertex_index(gVL);
  126. BOOST_CHECK(connected_components(gVL, make_vector_property_map<int>(get(vertex_index,gVL)))
  127. == static_cast<int>(num_cycles)
  128. );
  129. make_connected(gVL);
  130. BOOST_CHECK(connected_components(gVL, make_vector_property_map<int>(get(vertex_index,gVL)))
  131. == 1
  132. );
  133. BOOST_CHECK(num_edges(gVL) == num_cycles * cycle_size + num_cycles - 1);
  134. LLgraph_t gLL;
  135. num_cycles = 40;
  136. cycle_size = 40;
  137. make_disconnected_cycles(gLL, num_cycles, cycle_size);
  138. reset_edge_index(gLL);
  139. reset_vertex_index(gLL);
  140. BOOST_CHECK(connected_components(gLL, make_vector_property_map<int>(get(vertex_index,gLL)))
  141. == static_cast<int>(num_cycles));
  142. make_connected(gLL);
  143. BOOST_CHECK(connected_components(gLL, make_vector_property_map<int>(get(vertex_index,gLL)))
  144. == 1
  145. );
  146. BOOST_CHECK(num_edges(gLL) == num_cycles * cycle_size + num_cycles - 1);
  147. // Now make sure that no edges are added to an already connected graph
  148. // when you call make_connected again
  149. graph_traits<VVgraph_t>::edges_size_type VV_num_edges(num_edges(gVV));
  150. make_connected(gVV);
  151. BOOST_CHECK(num_edges(gVV) == VV_num_edges);
  152. graph_traits<VLgraph_t>::edges_size_type VL_num_edges(num_edges(gVL));
  153. make_connected(gVL);
  154. BOOST_CHECK(num_edges(gVL) == VL_num_edges);
  155. graph_traits<LVgraph_t>::edges_size_type LV_num_edges(num_edges(gLV));
  156. make_connected(gLV);
  157. BOOST_CHECK(num_edges(gLV) == LV_num_edges);
  158. graph_traits<LLgraph_t>::edges_size_type LL_num_edges(num_edges(gLL));
  159. make_connected(gLL);
  160. BOOST_CHECK(num_edges(gLL) == LL_num_edges);
  161. return 0;
  162. }