1 // Copyright (C) 2005, 2006 The Trustees of Indiana University.
3 // Use, modification and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 // Authors: Douglas Gregor
9 #define PBGL_ACCOUNTING
11 #include <boost/graph/use_mpi.hpp>
12 #include <boost/config.hpp>
13 #include <boost/throw_exception.hpp>
14 #include <boost/graph/distributed/delta_stepping_shortest_paths.hpp>
15 #include <boost/graph/distributed/mpi_process_group.hpp>
16 #include <boost/lexical_cast.hpp>
17 #include <boost/graph/parallel/distribution.hpp>
18 #include <boost/graph/erdos_renyi_generator.hpp>
19 #include <boost/graph/distributed/adjacency_list.hpp>
20 #include <boost/graph/graphviz.hpp>
21 #include <boost/random.hpp>
22 #include <boost/test/minimal.hpp>
23 #include <boost/graph/iteration_macros.hpp>
28 #ifdef BOOST_NO_EXCEPTIONS
30 boost::throw_exception(std::exception
const& ex
)
32 std::cout
<< ex
.what() << std::endl
;
37 /****************************************************************************
39 ****************************************************************************/
40 typedef double time_type
;
42 inline time_type
get_time()
47 std::string
print_time(time_type t
)
49 std::ostringstream out
;
50 out
<< std::setiosflags(std::ios::fixed
) << std::setprecision(2) << t
;
54 /****************************************************************************
55 * Edge weight generator iterator *
56 ****************************************************************************/
57 template<typename F
, typename RandomGenerator
>
58 class generator_iterator
61 typedef std::input_iterator_tag iterator_category
;
62 typedef typename
F::result_type value_type
;
63 typedef const value_type
& reference
;
64 typedef const value_type
* pointer
;
65 typedef void difference_type
;
68 generator_iterator(RandomGenerator
& gen
, const F
& f
= F())
74 reference
operator*() const { return value
; }
75 pointer
operator->() const { return &value
; }
77 generator_iterator
& operator++()
83 generator_iterator
operator++(int)
85 generator_iterator
temp(*this);
90 bool operator==(const generator_iterator
& other
) const
91 { return f
== other
.f
; }
93 bool operator!=(const generator_iterator
& other
) const
94 { return !(*this == other
); }
102 template<typename F
, typename RandomGenerator
>
103 inline generator_iterator
<F
, RandomGenerator
>
104 make_generator_iterator( RandomGenerator
& gen
, const F
& f
)
105 { return generator_iterator
<F
, RandomGenerator
>(gen
, f
); }
107 /****************************************************************************
109 ****************************************************************************/
110 template <typename Graph
, typename DistanceMap
, typename WeightMap
>
112 verify_shortest_paths(const Graph
& g
, DistanceMap distance
,
113 const WeightMap
& weight
) {
115 distance
.set_max_ghost_cells(0);
117 BGL_FORALL_VERTICES_T(v
, g
, Graph
) {
118 BGL_FORALL_OUTEDGES_T(v
, e
, g
, Graph
) {
119 get(distance
, target(e
, g
));
123 synchronize(process_group(g
));
125 BGL_FORALL_VERTICES_T(v
, g
, Graph
) {
126 BGL_FORALL_OUTEDGES_T(v
, e
, g
, Graph
) {
127 assert(get(distance
, target(e
, g
)) <=
128 get(distance
, source(e
, g
)) + get(weight
, e
));
133 using namespace boost
;
134 using boost::graph::distributed::mpi_process_group
;
136 typedef int weight_type
;
138 struct WeightedEdge
{
139 WeightedEdge(weight_type weight
= 0) : weight(weight
) { }
143 template<typename Archiver
>
144 void serialize(Archiver
& ar
, const unsigned int /*version*/)
150 struct VertexProperties
{
151 VertexProperties(int d
= 0)
156 template<typename Archiver
>
157 void serialize(Archiver
& ar
, const unsigned int /*version*/)
164 test_distributed_shortest_paths(int n
, double p
, int c
, int seed
)
166 typedef adjacency_list
<listS
,
167 distributedS
<mpi_process_group
, vecS
>,
172 typedef graph_traits
<Graph
>::vertices_size_type vertices_size_type
;
174 // Build a random number generator
178 // Build a random graph
179 Graph
g(erdos_renyi_iterator
<minstd_rand
, Graph
>(gen
, n
, p
),
180 erdos_renyi_iterator
<minstd_rand
, Graph
>(),
181 make_generator_iterator(gen
, uniform_int
<int>(0, c
)),
184 uniform_int
<vertices_size_type
> rand_vertex(0, n
);
186 graph::distributed::delta_stepping_shortest_paths(g
,
187 vertex(rand_vertex(gen
), g
),
188 dummy_property_map(),
189 get(&VertexProperties::distance
, g
),
190 get(&WeightedEdge::weight
, g
));
192 verify_shortest_paths(g
,
193 get(&VertexProperties::distance
, g
),
194 get(&WeightedEdge::weight
, g
));
197 int test_main(int argc
, char* argv
[])
199 mpi::environment
env(argc
, argv
);
206 if (argc
> 1) n
= lexical_cast
<int>(argv
[1]);
207 if (argc
> 2) p
= lexical_cast
<double>(argv
[2]);
208 if (argc
> 3) c
= lexical_cast
<int>(argv
[3]);
209 if (argc
> 4) seed
= lexical_cast
<int>(argv
[4]);
211 test_distributed_shortest_paths(n
, p
, c
, seed
);