crauser_et_al_shortest_paths.hpp 25 KB

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