// Copyright 2004 The Trustees of Indiana University. // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // Authors: Douglas Gregor // Andrew Lumsdaine #ifndef BOOST_GRAPH_DIJKSTRA_TESTING_DIETMAR #define BOOST_GRAPH_DIJKSTRA_TESTING #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace boost; #ifdef BOOST_GRAPH_DIJKSTRA_TESTING_DIETMAR struct show_events_visitor : dijkstra_visitor<> { template < typename Vertex, typename Graph > void discover_vertex(Vertex v, const Graph&) { std::cerr << "on_discover_vertex(" << v << ")\n"; } template < typename Vertex, typename Graph > void examine_vertex(Vertex v, const Graph&) { std::cerr << "on_discover_vertex(" << v << ")\n"; } }; template < typename Graph, typename Kind > void run_test(const Graph& g, const char* name, Kind kind, const std::vector< double >& correct_distances) { std::vector< double > distances(num_vertices(g)); std::cout << "Running Dijkstra's with " << name << "..."; std::cout.flush(); boost::timer::cpu_timer t; t.start(); dijkstra_heap_kind = kind; dijkstra_shortest_paths(g, vertex(0, g), distance_map(&distances[0]).visitor(show_events_visitor())); double run_time = t.stop(); std::cout << t.format() << " seconds.\n"; BOOST_TEST(distances == correct_distances); if (distances != correct_distances) { std::cout << "Expected: "; std::copy(correct_distances.begin(), correct_distances.end(), std::ostream_iterator< double >(std::cout, " ")); std::cout << "\nReceived: "; std::copy(distances.begin(), distances.end(), std::ostream_iterator< double >(std::cout, " ")); std::cout << std::endl; } } #endif int main(int argc, char* argv[]) { unsigned n = (argc > 1 ? lexical_cast< unsigned >(argv[1]) : 10000u); unsigned m = (argc > 2 ? lexical_cast< unsigned >(argv[2]) : 10 * n); int seed = (argc > 3 ? lexical_cast< int >(argv[3]) : 1); // Build random graph typedef adjacency_list< vecS, vecS, directedS, no_property, property< edge_weight_t, double > > Graph; std::cout << "Generating graph..."; std::cout.flush(); minstd_rand gen(seed); double p = double(m) / (double(n) * double(n)); Graph g(erdos_renyi_iterator< minstd_rand, Graph >(gen, n, p), erdos_renyi_iterator< minstd_rand, Graph >(), n); std::cout << n << " vertices, " << num_edges(g) << " edges.\n"; uniform_real< double > rand01(0.0, 1.0); graph_traits< Graph >::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) put(edge_weight, g, *ei, rand01(gen)); std::vector< double > binary_heap_distances(n); std::vector< double > relaxed_heap_distances(n); std::vector< double > no_color_map_distances(n); // Run binary or d-ary heap version std::cout << "Running Dijkstra's with binary heap..."; std::cout.flush(); boost::timer::cpu_timer t; t.start(); dijkstra_shortest_paths(g, vertex(0, g), distance_map(boost::make_iterator_property_map( binary_heap_distances.begin(), get(boost::vertex_index, g)))); t.stop(); boost::timer::cpu_times binary_heap_time = t.elapsed(); std::cout << boost::timer::format(binary_heap_time) << " seconds.\n"; std::cout << "Running Dijkstra's with d-ary heap (d=4)..."; std::cout.flush(); t.start(); dijkstra_shortest_paths(g, vertex(0, g), distance_map(boost::make_iterator_property_map( relaxed_heap_distances.begin(), get(boost::vertex_index, g)))); boost::timer::cpu_times relaxed_heap_time = t.elapsed(); std::cout << boost::timer::format(relaxed_heap_time) << " seconds.\n" << "Speedup = " << (binary_heap_time.user / relaxed_heap_time.user) << ".\n"; // Verify that the results are equivalent BOOST_TEST(binary_heap_distances == relaxed_heap_distances); // Run Michael's no-color-map version std::cout << "Running Dijkstra's (no color map) with d-ary heap (d=4)..."; std::cout.flush(); t.start(); dijkstra_shortest_paths_no_color_map(g, vertex(0, g), boost::dummy_property_map(), boost::make_iterator_property_map( no_color_map_distances.begin(), get(boost::vertex_index, g), 0.), get(boost::edge_weight, g), get(boost::vertex_index, g), std::less< double >(), boost::closed_plus< double >(), (std::numeric_limits< double >::max)(), 0, make_dijkstra_visitor(null_visitor())); boost::timer::cpu_times no_color_map_time = t.elapsed(); std::cout << boost::timer::format(no_color_map_time) << " seconds.\n" << "Speedup = " << (binary_heap_time.user / no_color_map_time.user) << ".\n"; // Verify that the results are equivalent BOOST_TEST(binary_heap_distances == no_color_map_distances); #ifdef BOOST_GRAPH_DIJKSTRA_TESTING_DIETMAR run_test(g, "d-ary heap (d=2)", dijkstra_d_heap_2, binary_heap_distances); run_test(g, "d-ary heap (d=3)", dijkstra_d_heap_3, binary_heap_distances); run_test( g, "Fibonacci heap", dijkstra_fibonacci_heap, binary_heap_distances); run_test(g, "Lazy Fibonacci heap", dijkstra_lazy_fibonacci_heap, binary_heap_distances); run_test(g, "Pairing heap", dijkstra_pairing_heap, binary_heap_distances); run_test(g, "Splay heap", dijkstra_splay_heap, binary_heap_distances); #endif return boost::report_errors(); }