crauser_et_al_shortest_paths.hpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  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. #ifdef PBGL_ACCOUNTING
  473. crauser_et_al_shortest_paths_stats.deleted_vertices.clear();
  474. crauser_et_al_shortest_paths_stats.execution_time = accounting::get_time();
  475. #endif
  476. // Property map that stores the lowest edge weight outgoing from
  477. // each vertex. If a vertex has no out-edges, the stored weight
  478. // is zero.
  479. typedef typename property_traits<WeightMap>::value_type weight_type;
  480. typedef iterator_property_map<weight_type*, IndexMap> MinOutWeightMap;
  481. std::vector<weight_type> min_out_weights_vec(num_vertices(g), inf);
  482. MinOutWeightMap min_out_weight(&min_out_weights_vec.front(), index_map);
  483. detail::initialize_min_out_weights(g, min_out_weight, weight, compare);
  484. // Property map that stores the lowest edge weight incoming to
  485. // each vertex. For undirected graphs, this will just be a
  486. // shallow copy of the version for outgoing edges.
  487. typedef typename graph_traits<DistributedGraph>::directed_category
  488. directed_category;
  489. const bool is_undirected =
  490. is_same<directed_category, undirected_tag>::value;
  491. typedef MinOutWeightMap MinInWeightMap;
  492. std::vector<weight_type>
  493. min_in_weights_vec(is_undirected? 1 : num_vertices(g), inf);
  494. MinInWeightMap min_in_weight(&min_in_weights_vec.front(), index_map);
  495. typedef typename graph_traits<DistributedGraph>::traversal_category
  496. category;
  497. detail::initialize_min_in_weights(g, min_in_weight, weight, inf, compare,
  498. directed_category(), category());
  499. // Initialize local portion of property maps
  500. typename graph_traits<DistributedGraph>::vertex_iterator ui, ui_end;
  501. for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
  502. put(distance, *ui, inf);
  503. put(predecessor, *ui, *ui);
  504. }
  505. put(distance, s, zero);
  506. // Dijkstra Queue
  507. typedef detail::crauser_et_al_dijkstra_queue
  508. <DistributedGraph, Combine, Compare, IndexMap, DistanceMap,
  509. PredecessorMap, MinOutWeightMap, MinInWeightMap>
  510. Queue;
  511. Queue Q(g, combine, compare, index_map, distance, predecessor,
  512. min_out_weight, is_undirected? min_out_weight : min_in_weight);
  513. // Parallel Dijkstra visitor
  514. ::boost::detail::dijkstra_bfs_visitor<
  515. DijkstraVisitor, Queue, WeightMap,
  516. boost::parallel::caching_property_map<PredecessorMap>,
  517. boost::parallel::caching_property_map<DistanceMap>, Combine, Compare
  518. > bfs_vis(vis, Q, weight,
  519. boost::parallel::make_caching_property_map(predecessor),
  520. boost::parallel::make_caching_property_map(distance),
  521. combine, compare, zero);
  522. set_property_map_role(vertex_color, color_map);
  523. set_property_map_role(vertex_distance, distance);
  524. breadth_first_search(g, s, Q, bfs_vis, color_map);
  525. #ifdef PBGL_ACCOUNTING
  526. crauser_et_al_shortest_paths_stats.execution_time =
  527. accounting::get_time() - crauser_et_al_shortest_paths_stats.execution_time;
  528. #endif
  529. }
  530. template<typename DistributedGraph, typename PredecessorMap,
  531. typename DistanceMap, typename WeightMap>
  532. void
  533. crauser_et_al_shortest_paths
  534. (const DistributedGraph& g,
  535. typename graph_traits<DistributedGraph>::vertex_descriptor s,
  536. PredecessorMap predecessor, DistanceMap distance, WeightMap weight)
  537. {
  538. typedef typename property_traits<DistanceMap>::value_type distance_type;
  539. std::vector<default_color_type> colors(num_vertices(g), white_color);
  540. crauser_et_al_shortest_paths(g, s, predecessor, distance, weight,
  541. get(vertex_index, g),
  542. make_iterator_property_map(&colors[0],
  543. get(vertex_index, g)),
  544. std::less<distance_type>(),
  545. closed_plus<distance_type>(),
  546. (std::numeric_limits<distance_type>::max)(),
  547. distance_type(),
  548. dijkstra_visitor<>());
  549. }
  550. template<typename DistributedGraph, typename PredecessorMap,
  551. typename DistanceMap>
  552. void
  553. crauser_et_al_shortest_paths
  554. (const DistributedGraph& g,
  555. typename graph_traits<DistributedGraph>::vertex_descriptor s,
  556. PredecessorMap predecessor, DistanceMap distance)
  557. {
  558. crauser_et_al_shortest_paths(g, s, predecessor, distance,
  559. get(edge_weight, g));
  560. }
  561. } // end namespace distributed
  562. #ifdef PBGL_ACCOUNTING
  563. using distributed::crauser_et_al_shortest_paths_stats;
  564. #endif
  565. using distributed::crauser_et_al_shortest_paths;
  566. } } // end namespace boost::graph
  567. #endif // BOOST_GRAPH_CRAUSER_ET_AL_SHORTEST_PATHS_HPP