incremental_components_test.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //=======================================================================
  2. // Copyright 2009 Trustees of Indiana University.
  3. // Authors: Michael Hansen, Andrew Lumsdaine
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. #include <iostream>
  10. #include <map>
  11. #include <set>
  12. #include <boost/foreach.hpp>
  13. #include <boost/graph/adjacency_list.hpp>
  14. #include <boost/graph/incremental_components.hpp>
  15. #include <boost/graph/random.hpp>
  16. #include <boost/lexical_cast.hpp>
  17. #include <boost/property_map/property_map.hpp>
  18. #include <boost/random.hpp>
  19. #include <boost/test/minimal.hpp>
  20. using namespace boost;
  21. typedef adjacency_list<vecS, vecS, undirectedS> VectorGraph;
  22. typedef adjacency_list<listS, listS, undirectedS,
  23. property<vertex_index_t, unsigned int> > ListGraph;
  24. template <typename Graph>
  25. void test_graph(const Graph& graph) {
  26. typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
  27. typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
  28. typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
  29. typedef typename property_map<Graph, vertex_index_t>::type IndexPropertyMap;
  30. typedef std::map<vertex_descriptor, vertices_size_type> RankMap;
  31. typedef associative_property_map<RankMap> RankPropertyMap;
  32. typedef std::vector<vertex_descriptor> ParentMap;
  33. typedef iterator_property_map<typename ParentMap::iterator,
  34. IndexPropertyMap, vertex_descriptor, vertex_descriptor&> IndexParentMap;
  35. RankMap rank_map;
  36. RankPropertyMap rank_property_map(rank_map);
  37. ParentMap parent_map(num_vertices(graph));
  38. IndexParentMap index_parent_map(parent_map.begin());
  39. // Create disjoint sets of vertices from the graph
  40. disjoint_sets<RankPropertyMap, IndexParentMap>
  41. vertex_sets(rank_property_map, index_parent_map);
  42. initialize_incremental_components(graph, vertex_sets);
  43. incremental_components(graph, vertex_sets);
  44. // Build component index from the graph's vertices, its index map,
  45. // and the disjoint sets.
  46. typedef component_index<vertices_size_type> Components;
  47. Components vertex_components(parent_map.begin(),
  48. parent_map.end(),
  49. get(boost::vertex_index, graph));
  50. // Create a reverse-lookup map for vertex indices
  51. std::vector<vertex_descriptor> reverse_index_map(num_vertices(graph));
  52. BOOST_FOREACH(vertex_descriptor vertex, vertices(graph)) {
  53. reverse_index_map[get(get(boost::vertex_index, graph), vertex)] = vertex;
  54. }
  55. // Verify that components are really connected
  56. BOOST_FOREACH(vertices_size_type component_index,
  57. vertex_components) {
  58. std::set<vertex_descriptor> component_vertices;
  59. BOOST_FOREACH(vertices_size_type child_index,
  60. vertex_components[component_index]) {
  61. vertex_descriptor child_vertex = reverse_index_map[child_index];
  62. component_vertices.insert(child_vertex);
  63. } // foreach child_index
  64. // Verify that children are connected to each other in some
  65. // manner, but not to vertices outside their component.
  66. BOOST_FOREACH(vertex_descriptor child_vertex,
  67. component_vertices) {
  68. // Skip orphan vertices
  69. if (out_degree(child_vertex, graph) == 0) {
  70. continue;
  71. }
  72. // Make sure at least one edge exists between [child_vertex] and
  73. // another vertex in the component.
  74. bool edge_exists = false;
  75. BOOST_FOREACH(edge_descriptor child_edge,
  76. out_edges(child_vertex, graph)) {
  77. if (component_vertices.count(target(child_edge, graph)) > 0) {
  78. edge_exists = true;
  79. break;
  80. }
  81. } // foreach child_edge
  82. BOOST_REQUIRE(edge_exists);
  83. } // foreach child_vertex
  84. } // foreach component_index
  85. } // test_graph
  86. int test_main(int argc, char* argv[])
  87. {
  88. std::size_t vertices_to_generate = 100,
  89. edges_to_generate = 50,
  90. random_seed = time(0);
  91. // Parse command-line arguments
  92. if (argc > 1) {
  93. vertices_to_generate = lexical_cast<std::size_t>(argv[1]);
  94. }
  95. if (argc > 2) {
  96. edges_to_generate = lexical_cast<std::size_t>(argv[2]);
  97. }
  98. if (argc > 3) {
  99. random_seed = lexical_cast<std::size_t>(argv[3]);
  100. }
  101. minstd_rand generator(random_seed);
  102. // Generate random vector and list graphs
  103. VectorGraph vector_graph;
  104. generate_random_graph(vector_graph, vertices_to_generate,
  105. edges_to_generate, generator, false);
  106. test_graph(vector_graph);
  107. ListGraph list_graph;
  108. generate_random_graph(list_graph, vertices_to_generate,
  109. edges_to_generate, generator, false);
  110. // Assign indices to list_graph's vertices
  111. graph_traits<ListGraph>::vertices_size_type index = 0;
  112. BOOST_FOREACH(graph_traits<ListGraph>::vertex_descriptor vertex,
  113. vertices(list_graph)) {
  114. put(get(boost::vertex_index, list_graph), vertex, index++);
  115. }
  116. test_graph(list_graph);
  117. return 0;
  118. }