mirror of
https://github.com/boostorg/graph.git
synced 2025-05-11 05:14:01 +00:00
171 lines
6.2 KiB
C++
171 lines
6.2 KiB
C++
// 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 <boost/graph/dijkstra_shortest_paths.hpp>
|
|
#include <boost/graph/dijkstra_shortest_paths_no_color_map.hpp>
|
|
#include <boost/graph/adjacency_list.hpp>
|
|
#include <boost/random/linear_congruential.hpp>
|
|
#include <boost/lexical_cast.hpp>
|
|
#include <boost/random/uniform_real.hpp>
|
|
#include <boost/timer/timer.hpp>
|
|
#include <vector>
|
|
#include <iostream>
|
|
|
|
#include <iterator>
|
|
#include <utility>
|
|
#include <boost/random/uniform_int.hpp>
|
|
#include <boost/graph/graph_traits.hpp>
|
|
#include <boost/graph/erdos_renyi_generator.hpp>
|
|
#include <boost/type_traits/is_base_and_derived.hpp>
|
|
#include <boost/type_traits/is_same.hpp>
|
|
#include <boost/detail/lightweight_test.hpp>
|
|
|
|
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();
|
|
}
|