/Src/Dependencies/Boost/boost/graph/distributed/crauser_et_al_shortest_paths.hpp

http://hadesmem.googlecode.com/ · C++ Header · 665 lines · 499 code · 91 blank · 75 comment · 27 complexity · 99c93bec9a1f11bfc311f4b898c6be3d MD5 · raw file

  1. // Copyright (C) 2004-2006 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. * This source file implements the variation on Dijkstra's algorithm *
  9. * presented by Crauser et al. in: *
  10. * *
  11. * Andreas Crauser, Kurt Mehlhorn, Ulrich Meyer, and Peter *
  12. * Sanders. A Parallelization of Dijkstra's Shortest Path *
  13. * Algorithm. In Lubos Brim, Jozef Gruska, and Jiri Zlatuska, *
  14. * editors, Mathematical Foundations of Computer Science (MFCS), *
  15. * volume 1450 of Lecture Notes in Computer Science, pages *
  16. * 722--731, 1998. Springer. *
  17. * *
  18. * This implementation is, however, restricted to the distributed-memory *
  19. * case, where the work is distributed by virtue of the vertices being *
  20. * distributed. In a shared-memory (single address space) context, we *
  21. * would want to add an explicit balancing step. *
  22. **************************************************************************/
  23. #ifndef BOOST_GRAPH_CRAUSER_ET_AL_SHORTEST_PATHS_HPP
  24. #define BOOST_GRAPH_CRAUSER_ET_AL_SHORTEST_PATHS_HPP
  25. #ifndef BOOST_GRAPH_USE_MPI
  26. #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
  27. #endif
  28. #include <boost/assert.hpp>
  29. #include <boost/graph/distributed/detail/dijkstra_shortest_paths.hpp>
  30. #include <boost/graph/parallel/algorithm.hpp>
  31. #include <functional>
  32. #include <boost/graph/iteration_macros.hpp>
  33. #include <boost/property_map/property_map_iterator.hpp>
  34. #include <boost/type_traits/is_same.hpp>
  35. #include <algorithm>
  36. #include <boost/property_map/parallel/caching_property_map.hpp>
  37. #include <boost/pending/indirect_cmp.hpp>
  38. #include <boost/graph/distributed/detail/remote_update_set.hpp>
  39. #include <vector>
  40. #include <boost/graph/breadth_first_search.hpp>
  41. #include <boost/graph/dijkstra_shortest_paths.hpp>
  42. #include <boost/graph/parallel/container_traits.hpp>
  43. #ifdef PBGL_ACCOUNTING
  44. # include <boost/graph/accounting.hpp>
  45. # include <numeric>
  46. #endif // PBGL_ACCOUNTING
  47. #ifdef MUTABLE_QUEUE
  48. # include <boost/pending/mutable_queue.hpp>
  49. #endif
  50. namespace boost { namespace graph { namespace distributed {
  51. #ifdef PBGL_ACCOUNTING
  52. struct crauser_et_al_shortest_paths_stats_t
  53. {
  54. /* Total wall-clock time used by the algorithm.*/
  55. accounting::time_type execution_time;
  56. /* The number of vertices deleted in each superstep. */
  57. std::vector<std::size_t> deleted_vertices;
  58. template<typename OutputStream>
  59. void print(OutputStream& out)
  60. {
  61. double avg_deletions = std::accumulate(deleted_vertices.begin(),
  62. deleted_vertices.end(),
  63. 0.0);
  64. avg_deletions /= deleted_vertices.size();
  65. out << "Problem = \"Single-Source Shortest Paths\"\n"
  66. << "Algorithm = \"Crauser et al\"\n"
  67. << "Function = crauser_et_al_shortest_paths\n"
  68. << "Wall clock time = " << accounting::print_time(execution_time)
  69. << "\nSupersteps = " << deleted_vertices.size() << "\n"
  70. << "Avg. deletions per superstep = " << avg_deletions << "\n";
  71. }
  72. };
  73. static crauser_et_al_shortest_paths_stats_t crauser_et_al_shortest_paths_stats;
  74. #endif
  75. namespace detail {
  76. /************************************************************************
  77. * Function objects that perform distance comparisons modified by the *
  78. * minimum or maximum edge weights. *
  79. ************************************************************************/
  80. template<typename Vertex, typename DistanceMap, typename MinInWeightMap,
  81. typename Combine, typename Compare>
  82. struct min_in_distance_compare
  83. : std::binary_function<Vertex, Vertex, bool>
  84. {
  85. min_in_distance_compare(DistanceMap d, MinInWeightMap m,
  86. Combine combine, Compare compare)
  87. : distance_map(d), min_in_weight(m), combine(combine),
  88. compare(compare)
  89. {
  90. }
  91. bool operator()(const Vertex& x, const Vertex& y) const
  92. {
  93. return compare(combine(get(distance_map, x), -get(min_in_weight, x)),
  94. combine(get(distance_map, y), -get(min_in_weight, y)));
  95. }
  96. private:
  97. DistanceMap distance_map;
  98. MinInWeightMap min_in_weight;
  99. Combine combine;
  100. Compare compare;
  101. };
  102. template<typename Vertex, typename DistanceMap, typename MinOutWeightMap,
  103. typename Combine, typename Compare>
  104. struct min_out_distance_compare
  105. : std::binary_function<Vertex, Vertex, bool>
  106. {
  107. min_out_distance_compare(DistanceMap d, MinOutWeightMap m,
  108. Combine combine, Compare compare)
  109. : distance_map(d), min_out_weight(m), combine(combine),
  110. compare(compare)
  111. {
  112. }
  113. bool operator()(const Vertex& x, const Vertex& y) const
  114. {
  115. return compare(combine(get(distance_map, x), get(min_out_weight, x)),
  116. combine(get(distance_map, y), get(min_out_weight, y)));
  117. }
  118. private:
  119. DistanceMap distance_map;
  120. MinOutWeightMap min_out_weight;
  121. Combine combine;
  122. Compare compare;
  123. };
  124. /************************************************************************/
  125. /************************************************************************
  126. * Dijkstra queue that implements Crauser et al.'s criteria. This queue *
  127. * actually stores three separate priority queues, to help expose all *
  128. * vertices that can be processed in a single phase. *
  129. ************************************************************************/
  130. template<typename Graph, typename Combine,
  131. typename Compare, typename VertexIndexMap, typename DistanceMap,
  132. typename PredecessorMap, typename MinOutWeightMap,
  133. typename MinInWeightMap>
  134. class crauser_et_al_dijkstra_queue
  135. : public graph::detail::remote_update_set<
  136. crauser_et_al_dijkstra_queue<
  137. Graph, Combine, Compare, VertexIndexMap, DistanceMap,
  138. PredecessorMap, MinOutWeightMap, MinInWeightMap>,
  139. typename boost::graph::parallel::process_group_type<Graph>::type,
  140. typename dijkstra_msg_value<DistanceMap, PredecessorMap>::type,
  141. typename property_map<Graph, vertex_owner_t>::const_type>
  142. {
  143. typedef typename graph_traits<Graph>::vertex_descriptor
  144. vertex_descriptor;
  145. typedef crauser_et_al_dijkstra_queue self_type;
  146. typedef dijkstra_msg_value<DistanceMap, PredecessorMap> msg_value_creator;
  147. typedef typename msg_value_creator::type msg_value_type;
  148. typedef typename graph_traits<Graph>::vertices_size_type
  149. vertices_size_type;
  150. typedef typename property_map<Graph, vertex_owner_t>::const_type
  151. OwnerPropertyMap;
  152. typedef typename boost::graph::parallel::process_group_type<Graph>::type
  153. process_group_type;
  154. typedef graph::detail::remote_update_set<self_type, process_group_type,
  155. msg_value_type, OwnerPropertyMap>
  156. inherited;
  157. // Priority queue for tentative distances
  158. typedef indirect_cmp<DistanceMap, Compare> dist_queue_compare_type;
  159. typedef typename property_traits<DistanceMap>::value_type distance_type;
  160. #ifdef MUTABLE_QUEUE
  161. typedef mutable_queue<vertex_descriptor, std::vector<vertex_descriptor>,
  162. dist_queue_compare_type, VertexIndexMap> dist_queue_type;
  163. #else
  164. typedef relaxed_heap<vertex_descriptor, dist_queue_compare_type,
  165. VertexIndexMap> dist_queue_type;
  166. #endif // MUTABLE_QUEUE
  167. // Priority queue for OUT criteria
  168. typedef min_out_distance_compare<vertex_descriptor, DistanceMap,
  169. MinOutWeightMap, Combine, Compare>
  170. out_queue_compare_type;
  171. #ifdef MUTABLE_QUEUE
  172. typedef mutable_queue<vertex_descriptor, std::vector<vertex_descriptor>,
  173. out_queue_compare_type, VertexIndexMap> out_queue_type;
  174. #else
  175. typedef relaxed_heap<vertex_descriptor, out_queue_compare_type,
  176. VertexIndexMap> out_queue_type;
  177. #endif // MUTABLE_QUEUE
  178. // Priority queue for IN criteria
  179. typedef min_in_distance_compare<vertex_descriptor, DistanceMap,
  180. MinInWeightMap, Combine, Compare>
  181. in_queue_compare_type;
  182. #ifdef MUTABLE_QUEUE
  183. typedef mutable_queue<vertex_descriptor, std::vector<vertex_descriptor>,
  184. in_queue_compare_type, VertexIndexMap> in_queue_type;
  185. #else
  186. typedef relaxed_heap<vertex_descriptor, in_queue_compare_type,
  187. VertexIndexMap> in_queue_type;
  188. #endif // MUTABLE_QUEUE
  189. typedef typename process_group_type::process_id_type process_id_type;
  190. public:
  191. typedef typename dist_queue_type::size_type size_type;
  192. typedef typename dist_queue_type::value_type value_type;
  193. crauser_et_al_dijkstra_queue(const Graph& g,
  194. const Combine& combine,
  195. const Compare& compare,
  196. const VertexIndexMap& id,
  197. const DistanceMap& distance_map,
  198. const PredecessorMap& predecessor_map,
  199. const MinOutWeightMap& min_out_weight,
  200. const MinInWeightMap& min_in_weight)
  201. : inherited(boost::graph::parallel::process_group(g), get(vertex_owner, g)),
  202. dist_queue(num_vertices(g),
  203. dist_queue_compare_type(distance_map, compare),
  204. id),
  205. out_queue(num_vertices(g),
  206. out_queue_compare_type(distance_map, min_out_weight,
  207. combine, compare),
  208. id),
  209. in_queue(num_vertices(g),
  210. in_queue_compare_type(distance_map, min_in_weight,
  211. combine, compare),
  212. id),
  213. g(g),
  214. distance_map(distance_map),
  215. predecessor_map(predecessor_map),
  216. min_out_weight(min_out_weight),
  217. min_in_weight(min_in_weight),
  218. min_distance(0),
  219. min_out_distance(0)
  220. #ifdef PBGL_ACCOUNTING
  221. , local_deletions(0)
  222. #endif
  223. { }
  224. void push(const value_type& x)
  225. {
  226. msg_value_type msg_value =
  227. msg_value_creator::create(get(distance_map, x),
  228. predecessor_value(get(predecessor_map, x)));
  229. inherited::update(x, msg_value);
  230. }
  231. void update(const value_type& x) { push(x); }
  232. void pop()
  233. {
  234. // Remove from distance queue
  235. dist_queue.remove(top_vertex);
  236. // Remove from OUT queue
  237. out_queue.remove(top_vertex);
  238. // Remove from IN queue
  239. in_queue.remove(top_vertex);
  240. #ifdef PBGL_ACCOUNTING
  241. ++local_deletions;
  242. #endif
  243. }
  244. vertex_descriptor& top() { return top_vertex; }
  245. const vertex_descriptor& top() const { return top_vertex; }
  246. bool empty()
  247. {
  248. inherited::collect();
  249. // If there are no suitable messages, wait until we get something
  250. while (!has_suitable_vertex()) {
  251. if (do_synchronize()) return true;
  252. }
  253. // Return true only if nobody has any messages; false if we
  254. // have suitable messages
  255. return false;
  256. }
  257. bool do_synchronize()
  258. {
  259. using boost::parallel::all_reduce;
  260. using boost::parallel::minimum;
  261. inherited::synchronize();
  262. // TBD: could use combine here, but then we need to stop using
  263. // minimum<distance_type>() as the function object.
  264. distance_type local_distances[2];
  265. local_distances[0] =
  266. dist_queue.empty()? (std::numeric_limits<distance_type>::max)()
  267. : get(distance_map, dist_queue.top());
  268. local_distances[1] =
  269. out_queue.empty()? (std::numeric_limits<distance_type>::max)()
  270. : (get(distance_map, out_queue.top())
  271. + get(min_out_weight, out_queue.top()));
  272. distance_type distances[2];
  273. all_reduce(this->process_group, local_distances, local_distances + 2,
  274. distances, minimum<distance_type>());
  275. min_distance = distances[0];
  276. min_out_distance = distances[1];
  277. #ifdef PBGL_ACCOUNTING
  278. std::size_t deletions = 0;
  279. all_reduce(this->process_group, &local_deletions, &local_deletions + 1,
  280. &deletions, std::plus<std::size_t>());
  281. if (process_id(this->process_group) == 0) {
  282. crauser_et_al_shortest_paths_stats.deleted_vertices.push_back(deletions);
  283. }
  284. local_deletions = 0;
  285. BOOST_ASSERT(deletions > 0);
  286. #endif
  287. return min_distance == (std::numeric_limits<distance_type>::max)();
  288. }
  289. private:
  290. vertex_descriptor predecessor_value(vertex_descriptor v) const
  291. { return v; }
  292. vertex_descriptor
  293. predecessor_value(property_traits<dummy_property_map>::reference) const
  294. { return graph_traits<Graph>::null_vertex(); }
  295. bool has_suitable_vertex() const
  296. {
  297. if (!dist_queue.empty()) {
  298. top_vertex = dist_queue.top();
  299. if (get(distance_map, dist_queue.top()) <= min_out_distance)
  300. return true;
  301. }
  302. if (!in_queue.empty()) {
  303. top_vertex = in_queue.top();
  304. return (get(distance_map, top_vertex)
  305. - get(min_in_weight, top_vertex)) <= min_distance;
  306. }
  307. return false;
  308. }
  309. public:
  310. void
  311. receive_update(process_id_type source, vertex_descriptor vertex,
  312. distance_type distance)
  313. {
  314. // Update the queue if the received distance is better than
  315. // the distance we know locally
  316. if (distance < get(distance_map, vertex)
  317. || (distance == get(distance_map, vertex)
  318. && source == process_id(this->process_group))) {
  319. // Update the local distance map
  320. put(distance_map, vertex, distance);
  321. bool is_in_queue = dist_queue.contains(vertex);
  322. if (!is_in_queue) {
  323. dist_queue.push(vertex);
  324. out_queue.push(vertex);
  325. in_queue.push(vertex);
  326. }
  327. else {
  328. dist_queue.update(vertex);
  329. out_queue.update(vertex);
  330. in_queue.update(vertex);
  331. }
  332. }
  333. }
  334. void
  335. receive_update(process_id_type source, vertex_descriptor vertex,
  336. std::pair<distance_type, vertex_descriptor> p)
  337. {
  338. if (p.first <= get(distance_map, vertex)) {
  339. put(predecessor_map, vertex, p.second);
  340. receive_update(source, vertex, p.first);
  341. }
  342. }
  343. private:
  344. dist_queue_type dist_queue;
  345. out_queue_type out_queue;
  346. in_queue_type in_queue;
  347. mutable value_type top_vertex;
  348. const Graph& g;
  349. DistanceMap distance_map;
  350. PredecessorMap predecessor_map;
  351. MinOutWeightMap min_out_weight;
  352. MinInWeightMap min_in_weight;
  353. distance_type min_distance;
  354. distance_type min_out_distance;
  355. #ifdef PBGL_ACCOUNTING
  356. std::size_t local_deletions;
  357. #endif
  358. };
  359. /************************************************************************/
  360. /************************************************************************
  361. * Initialize the property map that contains the minimum incoming edge *
  362. * weight for each vertex. There are separate implementations for *
  363. * directed, bidirectional, and undirected graph. *
  364. ************************************************************************/
  365. template<typename Graph, typename MinInWeightMap, typename WeightMap,
  366. typename Inf, typename Compare>
  367. void
  368. initialize_min_in_weights(const Graph& g, MinInWeightMap min_in_weight,
  369. WeightMap weight, Inf inf, Compare compare,
  370. directed_tag, incidence_graph_tag)
  371. {
  372. // Send minimum weights off to the owners
  373. set_property_map_role(vertex_distance, min_in_weight);
  374. BGL_FORALL_VERTICES_T(v, g, Graph) {
  375. BGL_FORALL_OUTEDGES_T(v, e, g, Graph) {
  376. if (get(weight, e) < get(min_in_weight, target(e, g)))
  377. put(min_in_weight, target(e, g), get(weight, e));
  378. }
  379. }
  380. using boost::graph::parallel::process_group;
  381. synchronize(process_group(g));
  382. // Replace any infinities with zeros
  383. BGL_FORALL_VERTICES_T(v, g, Graph) {
  384. if (get(min_in_weight, v) == inf) put(min_in_weight, v, 0);
  385. }
  386. }
  387. template<typename Graph, typename MinInWeightMap, typename WeightMap,
  388. typename Inf, typename Compare>
  389. void
  390. initialize_min_in_weights(const Graph& g, MinInWeightMap min_in_weight,
  391. WeightMap weight, Inf inf, Compare compare,
  392. directed_tag, bidirectional_graph_tag)
  393. {
  394. #if 0
  395. typename property_map<Graph, vertex_local_t>::const_type
  396. local = get(vertex_local, g);
  397. // This code assumes that the properties of the in-edges are
  398. // available locally. This is not necessarily the case, so don't
  399. // do this yet.
  400. set_property_map_role(vertex_distance, min_in_weight);
  401. BGL_FORALL_VERTICES_T(v, g, Graph) {
  402. if (in_edges(v, g).first != in_edges(v, g).second) {
  403. std::cerr << "weights(" << g.distribution().global(get(local, v))
  404. << ") = ";
  405. BGL_FORALL_INEDGES_T(v, e, g, Graph) {
  406. std::cerr << get(weight, e) << ' ';
  407. }
  408. std::cerr << std::endl;
  409. put(min_in_weight, v,
  410. *std::min_element
  411. (make_property_map_iterator(weight, in_edges(v, g).first),
  412. make_property_map_iterator(weight, in_edges(v, g).second),
  413. compare));
  414. } else {
  415. put(min_in_weight, v, 0);
  416. }
  417. std::cerr << "miw(" << g.distribution().global(get(local, v)) << ") = "
  418. << get(min_in_weight, v) << std::endl;
  419. }
  420. #else
  421. initialize_min_in_weights(g, min_in_weight, weight, inf, compare,
  422. directed_tag(), incidence_graph_tag());
  423. #endif
  424. }
  425. template<typename Graph, typename MinInWeightMap, typename WeightMap,
  426. typename Inf, typename Compare>
  427. inline void
  428. initialize_min_in_weights(const Graph&, MinInWeightMap, WeightMap, Inf,
  429. Compare, undirected_tag, bidirectional_graph_tag)
  430. {
  431. // In weights are the same as out weights, so do nothing
  432. }
  433. /************************************************************************/
  434. /************************************************************************
  435. * Initialize the property map that contains the minimum outgoing edge *
  436. * weight for each vertex. *
  437. ************************************************************************/
  438. template<typename Graph, typename MinOutWeightMap, typename WeightMap,
  439. typename Compare>
  440. void
  441. initialize_min_out_weights(const Graph& g, MinOutWeightMap min_out_weight,
  442. WeightMap weight, Compare compare)
  443. {
  444. typedef typename property_traits<WeightMap>::value_type weight_type;
  445. BGL_FORALL_VERTICES_T(v, g, Graph) {
  446. if (out_edges(v, g).first != out_edges(v, g).second) {
  447. put(min_out_weight, v,
  448. *std::min_element
  449. (make_property_map_iterator(weight, out_edges(v, g).first),
  450. make_property_map_iterator(weight, out_edges(v, g).second),
  451. compare));
  452. if (get(min_out_weight, v) < weight_type(0))
  453. boost::throw_exception(negative_edge());
  454. }
  455. }
  456. }
  457. /************************************************************************/
  458. } // end namespace detail
  459. template<typename DistributedGraph, typename DijkstraVisitor,
  460. typename PredecessorMap, typename DistanceMap, typename WeightMap,
  461. typename IndexMap, typename ColorMap, typename Compare,
  462. typename Combine, typename DistInf, typename DistZero>
  463. void
  464. crauser_et_al_shortest_paths
  465. (const DistributedGraph& g,
  466. typename graph_traits<DistributedGraph>::vertex_descriptor s,
  467. PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
  468. IndexMap index_map, ColorMap color_map,
  469. Compare compare, Combine combine, DistInf inf, DistZero zero,
  470. DijkstraVisitor vis)
  471. {
  472. typedef typename boost::graph::parallel::process_group_type<DistributedGraph>::type
  473. process_group_type;
  474. typedef typename process_group_type::process_id_type process_id_type;
  475. typedef typename graph_traits<DistributedGraph>::vertex_descriptor
  476. Vertex;
  477. typedef typename graph_traits<DistributedGraph>::vertices_size_type
  478. vertices_size_type;
  479. #ifdef PBGL_ACCOUNTING
  480. crauser_et_al_shortest_paths_stats.deleted_vertices.clear();
  481. crauser_et_al_shortest_paths_stats.execution_time = accounting::get_time();
  482. #endif
  483. // Property map that stores the lowest edge weight outgoing from
  484. // each vertex. If a vertex has no out-edges, the stored weight
  485. // is zero.
  486. typedef typename property_traits<WeightMap>::value_type weight_type;
  487. typedef iterator_property_map<weight_type*, IndexMap> MinOutWeightMap;
  488. std::vector<weight_type> min_out_weights_vec(num_vertices(g), inf);
  489. MinOutWeightMap min_out_weight(&min_out_weights_vec.front(), index_map);
  490. detail::initialize_min_out_weights(g, min_out_weight, weight, compare);
  491. // Property map that stores the lowest edge weight incoming to
  492. // each vertex. For undirected graphs, this will just be a
  493. // shallow copy of the version for outgoing edges.
  494. typedef typename graph_traits<DistributedGraph>::directed_category
  495. directed_category;
  496. const bool is_undirected =
  497. is_same<directed_category, undirected_tag>::value;
  498. typedef MinOutWeightMap MinInWeightMap;
  499. std::vector<weight_type>
  500. min_in_weights_vec(is_undirected? 1 : num_vertices(g), inf);
  501. MinInWeightMap min_in_weight(&min_in_weights_vec.front(), index_map);
  502. typedef typename graph_traits<DistributedGraph>::traversal_category
  503. category;
  504. detail::initialize_min_in_weights(g, min_in_weight, weight, inf, compare,
  505. directed_category(), category());
  506. // Initialize local portion of property maps
  507. typename graph_traits<DistributedGraph>::vertex_iterator ui, ui_end;
  508. for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
  509. put(distance, *ui, inf);
  510. put(predecessor, *ui, *ui);
  511. }
  512. put(distance, s, zero);
  513. // Dijkstra Queue
  514. typedef detail::crauser_et_al_dijkstra_queue
  515. <DistributedGraph, Combine, Compare, IndexMap, DistanceMap,
  516. PredecessorMap, MinOutWeightMap, MinInWeightMap>
  517. Queue;
  518. Queue Q(g, combine, compare, index_map, distance, predecessor,
  519. min_out_weight, is_undirected? min_out_weight : min_in_weight);
  520. // Parallel Dijkstra visitor
  521. ::boost::detail::dijkstra_bfs_visitor<
  522. DijkstraVisitor, Queue, WeightMap,
  523. boost::parallel::caching_property_map<PredecessorMap>,
  524. boost::parallel::caching_property_map<DistanceMap>, Combine, Compare
  525. > bfs_vis(vis, Q, weight,
  526. boost::parallel::make_caching_property_map(predecessor),
  527. boost::parallel::make_caching_property_map(distance),
  528. combine, compare, zero);
  529. set_property_map_role(vertex_color, color_map);
  530. set_property_map_role(vertex_distance, distance);
  531. breadth_first_search(g, s, Q, bfs_vis, color_map);
  532. #ifdef PBGL_ACCOUNTING
  533. crauser_et_al_shortest_paths_stats.execution_time =
  534. accounting::get_time() - crauser_et_al_shortest_paths_stats.execution_time;
  535. #endif
  536. }
  537. template<typename DistributedGraph, typename PredecessorMap,
  538. typename DistanceMap, typename WeightMap>
  539. void
  540. crauser_et_al_shortest_paths
  541. (const DistributedGraph& g,
  542. typename graph_traits<DistributedGraph>::vertex_descriptor s,
  543. PredecessorMap predecessor, DistanceMap distance, WeightMap weight)
  544. {
  545. typedef typename property_traits<DistanceMap>::value_type distance_type;
  546. std::vector<default_color_type> colors(num_vertices(g), white_color);
  547. crauser_et_al_shortest_paths(g, s, predecessor, distance, weight,
  548. get(vertex_index, g),
  549. make_iterator_property_map(&colors[0],
  550. get(vertex_index, g)),
  551. std::less<distance_type>(),
  552. closed_plus<distance_type>(),
  553. (std::numeric_limits<distance_type>::max)(),
  554. distance_type(),
  555. dijkstra_visitor<>());
  556. }
  557. template<typename DistributedGraph, typename PredecessorMap,
  558. typename DistanceMap>
  559. void
  560. crauser_et_al_shortest_paths
  561. (const DistributedGraph& g,
  562. typename graph_traits<DistributedGraph>::vertex_descriptor s,
  563. PredecessorMap predecessor, DistanceMap distance)
  564. {
  565. crauser_et_al_shortest_paths(g, s, predecessor, distance,
  566. get(edge_weight, g));
  567. }
  568. } // end namespace distributed
  569. #ifdef PBGL_ACCOUNTING
  570. using distributed::crauser_et_al_shortest_paths_stats;
  571. #endif
  572. using distributed::crauser_et_al_shortest_paths;
  573. } } // end namespace boost::graph
  574. #endif // BOOST_GRAPH_CRAUSER_ET_AL_SHORTEST_PATHS_HPP