dijkstra_heap_performance.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright 2004 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. #ifndef BOOST_GRAPH_DIJKSTRA_TESTING_DIETMAR
  8. # define BOOST_GRAPH_DIJKSTRA_TESTING
  9. #endif
  10. #include <boost/graph/dijkstra_shortest_paths.hpp>
  11. #include <boost/graph/dijkstra_shortest_paths_no_color_map.hpp>
  12. #include <boost/graph/adjacency_list.hpp>
  13. #include <boost/random/linear_congruential.hpp>
  14. #include <boost/lexical_cast.hpp>
  15. #include <boost/random/uniform_real.hpp>
  16. #include <boost/timer.hpp>
  17. #include <vector>
  18. #include <iostream>
  19. #include <iterator>
  20. #include <utility>
  21. #include <boost/random/uniform_int.hpp>
  22. #include <boost/graph/graph_traits.hpp>
  23. #include <boost/graph/erdos_renyi_generator.hpp>
  24. #include <boost/type_traits/is_base_and_derived.hpp>
  25. #include <boost/type_traits/is_same.hpp>
  26. #include <boost/detail/lightweight_test.hpp>
  27. using namespace boost;
  28. #ifdef BOOST_GRAPH_DIJKSTRA_TESTING_DIETMAR
  29. struct show_events_visitor : dijkstra_visitor<>
  30. {
  31. template<typename Vertex, typename Graph>
  32. void discover_vertex(Vertex v, const Graph&)
  33. {
  34. std::cerr << "on_discover_vertex(" << v << ")\n";
  35. }
  36. template<typename Vertex, typename Graph>
  37. void examine_vertex(Vertex v, const Graph&)
  38. {
  39. std::cerr << "on_discover_vertex(" << v << ")\n";
  40. }
  41. };
  42. template<typename Graph, typename Kind>
  43. void run_test(const Graph& g, const char* name, Kind kind,
  44. const std::vector<double>& correct_distances)
  45. {
  46. std::vector<double> distances(num_vertices(g));
  47. std::cout << "Running Dijkstra's with " << name << "...";
  48. std::cout.flush();
  49. timer t;
  50. dijkstra_heap_kind = kind;
  51. dijkstra_shortest_paths(g, vertex(0, g),
  52. distance_map(&distances[0]).
  53. visitor(show_events_visitor()));
  54. double run_time = t.elapsed();
  55. std::cout << run_time << " seconds.\n";
  56. BOOST_TEST(distances == correct_distances);
  57. if (distances != correct_distances)
  58. {
  59. std::cout << "Expected: ";
  60. std::copy(correct_distances.begin(), correct_distances.end(),
  61. std::ostream_iterator<double>(std::cout, " "));
  62. std::cout << "\nReceived: ";
  63. std::copy(distances.begin(), distances.end(),
  64. std::ostream_iterator<double>(std::cout, " "));
  65. std::cout << std::endl;
  66. }
  67. }
  68. #endif
  69. int main(int argc, char* argv[])
  70. {
  71. unsigned n = (argc > 1? lexical_cast<unsigned>(argv[1]) : 10000u);
  72. unsigned m = (argc > 2? lexical_cast<unsigned>(argv[2]) : 10*n);
  73. int seed = (argc > 3? lexical_cast<int>(argv[3]) : 1);
  74. // Build random graph
  75. typedef adjacency_list<vecS, vecS, directedS, no_property,
  76. property<edge_weight_t, double> > Graph;
  77. std::cout << "Generating graph...";
  78. std::cout.flush();
  79. minstd_rand gen(seed);
  80. double p = double(m)/(double(n)*double(n));
  81. Graph g(erdos_renyi_iterator<minstd_rand, Graph>(gen, n, p),
  82. erdos_renyi_iterator<minstd_rand, Graph>(),
  83. n);
  84. std::cout << n << " vertices, " << num_edges(g) << " edges.\n";
  85. uniform_real<double> rand01(0.0, 1.0);
  86. graph_traits<Graph>::edge_iterator ei, ei_end;
  87. for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
  88. put(edge_weight, g, *ei, rand01(gen));
  89. std::vector<double> binary_heap_distances(n);
  90. std::vector<double> relaxed_heap_distances(n);
  91. std::vector<double> no_color_map_distances(n);
  92. // Run binary or d-ary heap version
  93. std::cout << "Running Dijkstra's with binary heap...";
  94. std::cout.flush();
  95. timer t;
  96. dijkstra_shortest_paths(g, vertex(0, g),
  97. distance_map(
  98. boost::make_iterator_property_map(
  99. binary_heap_distances.begin(), get(boost::vertex_index, g))));
  100. double binary_heap_time = t.elapsed();
  101. std::cout << binary_heap_time << " seconds.\n";
  102. std::cout << "Running Dijkstra's with d-ary heap (d=4)...";
  103. std::cout.flush();
  104. t.restart();
  105. dijkstra_shortest_paths(g, vertex(0, g),
  106. distance_map(
  107. boost::make_iterator_property_map(
  108. relaxed_heap_distances.begin(), get(boost::vertex_index, g))));
  109. double relaxed_heap_time = t.elapsed();
  110. std::cout << relaxed_heap_time << " seconds.\n"
  111. << "Speedup = " << (binary_heap_time / relaxed_heap_time) << ".\n";
  112. // Verify that the results are equivalent
  113. BOOST_TEST(binary_heap_distances == relaxed_heap_distances);
  114. // Run Michael's no-color-map version
  115. std::cout << "Running Dijkstra's (no color map) with d-ary heap (d=4)...";
  116. std::cout.flush();
  117. t.restart();
  118. dijkstra_shortest_paths_no_color_map
  119. (g, vertex(0, g),
  120. boost::dummy_property_map(),
  121. boost::make_iterator_property_map(no_color_map_distances.begin(),
  122. get(boost::vertex_index, g),
  123. 0.),
  124. get(boost::edge_weight, g),
  125. get(boost::vertex_index, g),
  126. std::less<double>(),
  127. boost::closed_plus<double>(),
  128. (std::numeric_limits<double>::max)(),
  129. 0,
  130. make_dijkstra_visitor(null_visitor())
  131. );
  132. double no_color_map_time = t.elapsed();
  133. std::cout << no_color_map_time << " seconds.\n"
  134. << "Speedup = " << (binary_heap_time / no_color_map_time) << ".\n";
  135. // Verify that the results are equivalent
  136. BOOST_TEST(binary_heap_distances == no_color_map_distances);
  137. #ifdef BOOST_GRAPH_DIJKSTRA_TESTING_DIETMAR
  138. run_test(g, "d-ary heap (d=2)", dijkstra_d_heap_2, binary_heap_distances);
  139. run_test(g, "d-ary heap (d=3)", dijkstra_d_heap_3, binary_heap_distances);
  140. run_test(g, "Fibonacci heap", dijkstra_fibonacci_heap, binary_heap_distances);
  141. run_test(g, "Lazy Fibonacci heap", dijkstra_lazy_fibonacci_heap, binary_heap_distances);
  142. run_test(g, "Pairing heap", dijkstra_pairing_heap, binary_heap_distances);
  143. run_test(g, "Splay heap", dijkstra_splay_heap, binary_heap_distances);
  144. #endif
  145. return boost::report_errors();
  146. }