hohberg_biconnected_components_test.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // Copyright (C) 2005-2008 The Trustees of Indiana University.
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Authors: Douglas Gregor
  6. // Andrew Lumsdaine
  7. //
  8. // Test of Hohberg's distributed biconnected components algorithm.
  9. #include <boost/graph/use_mpi.hpp>
  10. #include <boost/config.hpp>
  11. #include <boost/throw_exception.hpp>
  12. #include <boost/graph/distributed/hohberg_biconnected_components.hpp>
  13. #include <boost/graph/distributed/mpi_process_group.hpp>
  14. #include <boost/graph/distributed/adjacency_list.hpp>
  15. #include <boost/test/minimal.hpp>
  16. #ifdef BOOST_NO_EXCEPTIONS
  17. void
  18. boost::throw_exception(std::exception const& ex)
  19. {
  20. std::cout << ex.what() << std::endl;
  21. abort();
  22. }
  23. #endif
  24. using boost::graph::distributed::mpi_process_group;
  25. using namespace boost;
  26. template<typename Graph>
  27. void check_components(const Graph& g, std::size_t num_comps)
  28. {
  29. std::size_t not_mapped = (std::numeric_limits<std::size_t>::max)();
  30. std::vector<std::size_t> color_to_name(num_comps, not_mapped);
  31. BGL_FORALL_EDGES_T(e, g, Graph) {
  32. BOOST_CHECK(get(edge_color, g, e) < num_comps);
  33. if (color_to_name[get(edge_color, g, e)] == not_mapped)
  34. color_to_name[get(edge_color, g, e)] = get(edge_name, g, e);
  35. BOOST_CHECK(color_to_name[get(edge_color,g,e)] == get(edge_name,g,e));
  36. if (color_to_name[get(edge_color,g,e)] != get(edge_name,g,e)) {
  37. for (std::size_t i = 0; i < color_to_name.size(); ++i)
  38. std::cerr << color_to_name[i] << ' ';
  39. std::cerr << std::endl;
  40. std::cerr << color_to_name[get(edge_color,g,e)] << " != "
  41. << get(edge_name,g,e) << " on edge "
  42. << local(source(e, g)) << " -> " << local(target(e, g))
  43. << std::endl;
  44. }
  45. }
  46. }
  47. template<typename Graph>
  48. void
  49. test_small_hohberg_biconnected_components(Graph& g, int n, int comps_expected,
  50. bool single_component = true)
  51. {
  52. using boost::graph::distributed::hohberg_biconnected_components;
  53. bool is_root = (process_id(process_group(g)) == 0);
  54. if (single_component) {
  55. for (int i = 0; i < n; ++i) {
  56. if (is_root) std::cerr << "Testing with leader = " << i << std::endl;
  57. // Scramble edge_color_map
  58. BGL_FORALL_EDGES_T(e, g, Graph)
  59. put(edge_color, g, e, 17);
  60. typename graph_traits<Graph>::vertex_descriptor leader = vertex(i, g);
  61. int num_comps =
  62. hohberg_biconnected_components(g, get(edge_color, g), &leader,
  63. &leader + 1);
  64. BOOST_CHECK(num_comps == comps_expected);
  65. check_components(g, num_comps);
  66. }
  67. }
  68. if (is_root) std::cerr << "Testing simple interface." << std::endl;
  69. synchronize(g);
  70. // Scramble edge_color_map
  71. int i = 0;
  72. BGL_FORALL_EDGES_T(e, g, Graph) {
  73. ++i;
  74. put(edge_color, g, e, 17);
  75. }
  76. std::cerr << process_id(process_group(g)) << " has "
  77. << i << " edges.\n";
  78. int num_comps = hohberg_biconnected_components(g, get(edge_color, g));
  79. BOOST_CHECK(num_comps == comps_expected);
  80. check_components(g, num_comps);
  81. }
  82. int test_main(int argc, char* argv[])
  83. {
  84. mpi::environment env(argc, argv);
  85. typedef adjacency_list<listS,
  86. distributedS<mpi_process_group, vecS>,
  87. undirectedS,
  88. // Vertex properties
  89. no_property,
  90. // Edge properties
  91. property<edge_name_t, std::size_t,
  92. property<edge_color_t, std::size_t> > > Graph;
  93. typedef std::pair<int, int> E;
  94. {
  95. // Example 1: A single component with 2 bicomponents
  96. E edges_init[] = { E(0, 1), E(0, 2), E(1, 3), E(2, 4), E(3, 4), E(4, 5),
  97. E(4, 6), E(5, 6) };
  98. const int m = sizeof(edges_init) / sizeof(E);
  99. std::size_t expected_components[m] = { 0, 0, 0, 0, 0, 1, 1, 1 };
  100. const int n = 7;
  101. Graph g(&edges_init[0], &edges_init[0] + m, &expected_components[0], n);
  102. int num_comps_expected =
  103. *std::max_element(&expected_components[0], &expected_components[0] + m)
  104. + 1;
  105. test_small_hohberg_biconnected_components(g, n, num_comps_expected);
  106. }
  107. {
  108. // Example 2: A single component with 4 bicomponents
  109. E edges_init[] = { E(0, 1), E(1, 2), E(2, 0), E(2, 3), E(3, 4), E(4, 5),
  110. E(5, 2), E(3, 6), E(6, 7), E(7, 8), E(8, 6) };
  111. const int m = sizeof(edges_init) / sizeof(E);
  112. std::size_t expected_components[m] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 3, 3 };
  113. const int n = 9;
  114. Graph g(&edges_init[0], &edges_init[0] + m, &expected_components[0], n);
  115. int num_comps_expected =
  116. *std::max_element(&expected_components[0], &expected_components[0] + m)
  117. + 1;
  118. test_small_hohberg_biconnected_components(g, n, num_comps_expected);
  119. }
  120. {
  121. // Example 3: Two components, 6 bicomponents
  122. // This is just the concatenation of the two previous graphs.
  123. E edges_init[] = { /* Example 1 graph */
  124. E(0, 1), E(0, 2), E(1, 3), E(2, 4), E(3, 4), E(4, 5),
  125. E(4, 6), E(5, 6),
  126. /* Example 2 graph */
  127. E(7, 8), E(8, 9), E(9, 7), E(9, 10), E(10, 11),
  128. E(11, 12), E(12, 9), E(10, 13), E(13, 14), E(14, 15),
  129. E(15, 13) };
  130. const int m = sizeof(edges_init) / sizeof(E);
  131. std::size_t expected_components[m] =
  132. { /* Example 1 */0, 0, 0, 0, 0, 1, 1, 1,
  133. /* Example 2 */2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5 };
  134. const int n = 16;
  135. Graph g(&edges_init[0], &edges_init[0] + m, &expected_components[0], n);
  136. int num_comps_expected =
  137. *std::max_element(&expected_components[0], &expected_components[0] + m)
  138. + 1;
  139. test_small_hohberg_biconnected_components(g, n, num_comps_expected,
  140. false);
  141. }
  142. return 0;
  143. }