dijkstra_shortest_paths.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. //=======================================================================
  2. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  3. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. //
  10. //
  11. // Revision History:
  12. // 04 April 2001: Added named parameter variant. (Jeremy Siek)
  13. // 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
  14. //
  15. #ifndef BOOST_GRAPH_DIJKSTRA_HPP
  16. #define BOOST_GRAPH_DIJKSTRA_HPP
  17. #include <functional>
  18. #include <boost/limits.hpp>
  19. #include <boost/graph/named_function_params.hpp>
  20. #include <boost/graph/breadth_first_search.hpp>
  21. #include <boost/graph/relax.hpp>
  22. #include <boost/pending/indirect_cmp.hpp>
  23. #include <boost/graph/exception.hpp>
  24. #include <boost/pending/relaxed_heap.hpp>
  25. #include <boost/graph/overloading.hpp>
  26. #include <boost/smart_ptr.hpp>
  27. #include <boost/graph/detail/d_ary_heap.hpp>
  28. #include <boost/graph/two_bit_color_map.hpp>
  29. #include <boost/property_map/property_map.hpp>
  30. #include <boost/property_map/vector_property_map.hpp>
  31. #include <boost/type_traits.hpp>
  32. #include <boost/concept/assert.hpp>
  33. #ifdef BOOST_GRAPH_DIJKSTRA_TESTING
  34. # include <boost/pending/mutable_queue.hpp>
  35. #endif // BOOST_GRAPH_DIJKSTRA_TESTING
  36. namespace boost {
  37. /**
  38. * @brief Updates a particular value in a queue used by Dijkstra's
  39. * algorithm.
  40. *
  41. * This routine is called by Dijkstra's algorithm after it has
  42. * decreased the distance from the source vertex to the given @p
  43. * vertex. By default, this routine will just call @c
  44. * Q.update(vertex). However, other queues may provide more
  45. * specialized versions of this routine.
  46. *
  47. * @param Q the queue that will be updated.
  48. * @param vertex the vertex whose distance has been updated
  49. * @param old_distance the previous distance to @p vertex
  50. */
  51. template<typename Buffer, typename Vertex, typename DistanceType>
  52. inline void
  53. dijkstra_queue_update(Buffer& Q, Vertex vertex, DistanceType old_distance)
  54. {
  55. (void)old_distance;
  56. Q.update(vertex);
  57. }
  58. #ifdef BOOST_GRAPH_DIJKSTRA_TESTING
  59. // This is a misnomer now: it now just refers to the "default heap", which is
  60. // currently d-ary (d=4) but can be changed by a #define.
  61. static bool dijkstra_relaxed_heap = true;
  62. #endif
  63. template <class Visitor, class Graph>
  64. struct DijkstraVisitorConcept {
  65. void constraints() {
  66. BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept<Visitor> ));
  67. vis.initialize_vertex(u, g);
  68. vis.discover_vertex(u, g);
  69. vis.examine_vertex(u, g);
  70. vis.examine_edge(e, g);
  71. vis.edge_relaxed(e, g);
  72. vis.edge_not_relaxed(e, g);
  73. vis.finish_vertex(u, g);
  74. }
  75. Visitor vis;
  76. Graph g;
  77. typename graph_traits<Graph>::vertex_descriptor u;
  78. typename graph_traits<Graph>::edge_descriptor e;
  79. };
  80. template <class Visitors = null_visitor>
  81. class dijkstra_visitor : public bfs_visitor<Visitors> {
  82. public:
  83. dijkstra_visitor() { }
  84. dijkstra_visitor(Visitors vis)
  85. : bfs_visitor<Visitors>(vis) { }
  86. template <class Edge, class Graph>
  87. void edge_relaxed(Edge e, Graph& g) {
  88. invoke_visitors(this->m_vis, e, g, on_edge_relaxed());
  89. }
  90. template <class Edge, class Graph>
  91. void edge_not_relaxed(Edge e, Graph& g) {
  92. invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed());
  93. }
  94. private:
  95. template <class Edge, class Graph>
  96. void tree_edge(Edge u, Graph& g) { }
  97. };
  98. template <class Visitors>
  99. dijkstra_visitor<Visitors>
  100. make_dijkstra_visitor(Visitors vis) {
  101. return dijkstra_visitor<Visitors>(vis);
  102. }
  103. typedef dijkstra_visitor<> default_dijkstra_visitor;
  104. namespace detail {
  105. template <class UniformCostVisitor, class UpdatableQueue,
  106. class WeightMap, class PredecessorMap, class DistanceMap,
  107. class BinaryFunction, class BinaryPredicate>
  108. struct dijkstra_bfs_visitor
  109. {
  110. typedef typename property_traits<DistanceMap>::value_type D;
  111. typedef typename property_traits<WeightMap>::value_type W;
  112. dijkstra_bfs_visitor(UniformCostVisitor vis, UpdatableQueue& Q,
  113. WeightMap w, PredecessorMap p, DistanceMap d,
  114. BinaryFunction combine, BinaryPredicate compare,
  115. D zero)
  116. : m_vis(vis), m_Q(Q), m_weight(w), m_predecessor(p), m_distance(d),
  117. m_combine(combine), m_compare(compare), m_zero(zero) { }
  118. template <class Edge, class Graph>
  119. void tree_edge(Edge e, Graph& g) {
  120. bool decreased = relax(e, g, m_weight, m_predecessor, m_distance,
  121. m_combine, m_compare);
  122. if (decreased)
  123. m_vis.edge_relaxed(e, g);
  124. else
  125. m_vis.edge_not_relaxed(e, g);
  126. }
  127. template <class Edge, class Graph>
  128. void gray_target(Edge e, Graph& g) {
  129. D old_distance = get(m_distance, target(e, g));
  130. bool decreased = relax(e, g, m_weight, m_predecessor, m_distance,
  131. m_combine, m_compare);
  132. if (decreased) {
  133. dijkstra_queue_update(m_Q, target(e, g), old_distance);
  134. m_vis.edge_relaxed(e, g);
  135. } else
  136. m_vis.edge_not_relaxed(e, g);
  137. }
  138. template <class Vertex, class Graph>
  139. void initialize_vertex(Vertex u, Graph& g)
  140. { m_vis.initialize_vertex(u, g); }
  141. template <class Edge, class Graph>
  142. void non_tree_edge(Edge, Graph&) { }
  143. template <class Vertex, class Graph>
  144. void discover_vertex(Vertex u, Graph& g) { m_vis.discover_vertex(u, g); }
  145. template <class Vertex, class Graph>
  146. void examine_vertex(Vertex u, Graph& g) { m_vis.examine_vertex(u, g); }
  147. template <class Edge, class Graph>
  148. void examine_edge(Edge e, Graph& g) {
  149. // Test for negative-weight edges:
  150. //
  151. // Reasons that other comparisons do not work:
  152. //
  153. // m_compare(e_weight, D(0)):
  154. // m_compare only needs to work on distances, not weights, and those
  155. // types do not need to be the same (bug 8398,
  156. // https://svn.boost.org/trac/boost/ticket/8398).
  157. // m_compare(m_combine(source_dist, e_weight), source_dist):
  158. // if m_combine is project2nd (as in prim_minimum_spanning_tree),
  159. // this test will claim that the edge weight is negative whenever
  160. // the edge weight is less than source_dist, even if both of those
  161. // are positive (bug 9012,
  162. // https://svn.boost.org/trac/boost/ticket/9012).
  163. // m_compare(m_combine(e_weight, source_dist), source_dist):
  164. // would fix project2nd issue, but documentation only requires that
  165. // m_combine be able to take a distance and a weight (in that order)
  166. // and return a distance.
  167. // W e_weight = get(m_weight, e);
  168. // sd_plus_ew = source_dist + e_weight.
  169. // D sd_plus_ew = m_combine(source_dist, e_weight);
  170. // sd_plus_2ew = source_dist + 2 * e_weight.
  171. // D sd_plus_2ew = m_combine(sd_plus_ew, e_weight);
  172. // The test here is equivalent to e_weight < 0 if m_combine has a
  173. // cancellation law, but always returns false when m_combine is a
  174. // projection operator.
  175. if (m_compare(m_combine(m_zero, get(m_weight, e)), m_zero))
  176. boost::throw_exception(negative_edge());
  177. // End of test for negative-weight edges.
  178. m_vis.examine_edge(e, g);
  179. }
  180. template <class Edge, class Graph>
  181. void black_target(Edge, Graph&) { }
  182. template <class Vertex, class Graph>
  183. void finish_vertex(Vertex u, Graph& g) { m_vis.finish_vertex(u, g); }
  184. UniformCostVisitor m_vis;
  185. UpdatableQueue& m_Q;
  186. WeightMap m_weight;
  187. PredecessorMap m_predecessor;
  188. DistanceMap m_distance;
  189. BinaryFunction m_combine;
  190. BinaryPredicate m_compare;
  191. D m_zero;
  192. };
  193. } // namespace detail
  194. namespace detail {
  195. template <class Graph, class IndexMap, class Value, bool KnownNumVertices>
  196. struct vertex_property_map_generator_helper {};
  197. template <class Graph, class IndexMap, class Value>
  198. struct vertex_property_map_generator_helper<Graph, IndexMap, Value, true> {
  199. typedef boost::iterator_property_map<Value*, IndexMap> type;
  200. static type build(const Graph& g, const IndexMap& index, boost::scoped_array<Value>& array_holder) {
  201. array_holder.reset(new Value[num_vertices(g)]);
  202. std::fill(array_holder.get(), array_holder.get() + num_vertices(g), Value());
  203. return make_iterator_property_map(array_holder.get(), index);
  204. }
  205. };
  206. template <class Graph, class IndexMap, class Value>
  207. struct vertex_property_map_generator_helper<Graph, IndexMap, Value, false> {
  208. typedef boost::vector_property_map<Value, IndexMap> type;
  209. static type build(const Graph& g, const IndexMap& index, boost::scoped_array<Value>& array_holder) {
  210. return boost::make_vector_property_map<Value>(index);
  211. }
  212. };
  213. template <class Graph, class IndexMap, class Value>
  214. struct vertex_property_map_generator {
  215. typedef boost::is_base_and_derived<
  216. boost::vertex_list_graph_tag,
  217. typename boost::graph_traits<Graph>::traversal_category>
  218. known_num_vertices;
  219. typedef vertex_property_map_generator_helper<Graph, IndexMap, Value, known_num_vertices::value> helper;
  220. typedef typename helper::type type;
  221. static type build(const Graph& g, const IndexMap& index, boost::scoped_array<Value>& array_holder) {
  222. return helper::build(g, index, array_holder);
  223. }
  224. };
  225. }
  226. namespace detail {
  227. template <class Graph, class IndexMap, bool KnownNumVertices>
  228. struct default_color_map_generator_helper {};
  229. template <class Graph, class IndexMap>
  230. struct default_color_map_generator_helper<Graph, IndexMap, true> {
  231. typedef boost::two_bit_color_map<IndexMap> type;
  232. static type build(const Graph& g, const IndexMap& index) {
  233. size_t nv = num_vertices(g);
  234. return boost::two_bit_color_map<IndexMap>(nv, index);
  235. }
  236. };
  237. template <class Graph, class IndexMap>
  238. struct default_color_map_generator_helper<Graph, IndexMap, false> {
  239. typedef boost::vector_property_map<boost::two_bit_color_type, IndexMap> type;
  240. static type build(const Graph& g, const IndexMap& index) {
  241. return boost::make_vector_property_map<boost::two_bit_color_type>(index);
  242. }
  243. };
  244. template <class Graph, class IndexMap>
  245. struct default_color_map_generator {
  246. typedef boost::is_base_and_derived<
  247. boost::vertex_list_graph_tag,
  248. typename boost::graph_traits<Graph>::traversal_category>
  249. known_num_vertices;
  250. typedef default_color_map_generator_helper<Graph, IndexMap, known_num_vertices::value> helper;
  251. typedef typename helper::type type;
  252. static type build(const Graph& g, const IndexMap& index) {
  253. return helper::build(g, index);
  254. }
  255. };
  256. }
  257. // Call breadth first search with default color map.
  258. template <class Graph, class SourceInputIter, class DijkstraVisitor,
  259. class PredecessorMap, class DistanceMap,
  260. class WeightMap, class IndexMap, class Compare, class Combine,
  261. class DistZero>
  262. inline void
  263. dijkstra_shortest_paths_no_init
  264. (const Graph& g,
  265. SourceInputIter s_begin, SourceInputIter s_end,
  266. PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
  267. IndexMap index_map,
  268. Compare compare, Combine combine, DistZero zero,
  269. DijkstraVisitor vis)
  270. {
  271. typedef
  272. detail::default_color_map_generator<Graph, IndexMap>
  273. ColorMapHelper;
  274. typedef typename ColorMapHelper::type ColorMap;
  275. ColorMap color =
  276. ColorMapHelper::build(g, index_map);
  277. dijkstra_shortest_paths_no_init( g, s_begin, s_end, predecessor, distance, weight,
  278. index_map, compare, combine, zero, vis,
  279. color);
  280. }
  281. // Call breadth first search with default color map.
  282. template <class Graph, class DijkstraVisitor,
  283. class PredecessorMap, class DistanceMap,
  284. class WeightMap, class IndexMap, class Compare, class Combine,
  285. class DistZero>
  286. inline void
  287. dijkstra_shortest_paths_no_init
  288. (const Graph& g,
  289. typename graph_traits<Graph>::vertex_descriptor s,
  290. PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
  291. IndexMap index_map,
  292. Compare compare, Combine combine, DistZero zero,
  293. DijkstraVisitor vis)
  294. {
  295. dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance,
  296. weight, index_map, compare, combine, zero,
  297. vis);
  298. }
  299. // Call breadth first search
  300. template <class Graph, class SourceInputIter, class DijkstraVisitor,
  301. class PredecessorMap, class DistanceMap,
  302. class WeightMap, class IndexMap, class Compare, class Combine,
  303. class DistZero, class ColorMap>
  304. inline void
  305. dijkstra_shortest_paths_no_init
  306. (const Graph& g,
  307. SourceInputIter s_begin, SourceInputIter s_end,
  308. PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
  309. IndexMap index_map,
  310. Compare compare, Combine combine, DistZero zero,
  311. DijkstraVisitor vis, ColorMap color)
  312. {
  313. typedef indirect_cmp<DistanceMap, Compare> IndirectCmp;
  314. IndirectCmp icmp(distance, compare);
  315. typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
  316. #ifdef BOOST_GRAPH_DIJKSTRA_TESTING
  317. if (!dijkstra_relaxed_heap) {
  318. typedef mutable_queue<Vertex, std::vector<Vertex>, IndirectCmp, IndexMap>
  319. MutableQueue;
  320. MutableQueue Q(num_vertices(g), icmp, index_map);
  321. detail::dijkstra_bfs_visitor<DijkstraVisitor, MutableQueue, WeightMap,
  322. PredecessorMap, DistanceMap, Combine, Compare>
  323. bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero);
  324. breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color);
  325. return;
  326. }
  327. #endif // BOOST_GRAPH_DIJKSTRA_TESTING
  328. #ifdef BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP
  329. typedef relaxed_heap<Vertex, IndirectCmp, IndexMap> MutableQueue;
  330. MutableQueue Q(num_vertices(g), icmp, index_map);
  331. #else // Now the default: use a d-ary heap
  332. boost::scoped_array<std::size_t> index_in_heap_map_holder;
  333. typedef
  334. detail::vertex_property_map_generator<Graph, IndexMap, std::size_t>
  335. IndexInHeapMapHelper;
  336. typedef typename IndexInHeapMapHelper::type IndexInHeapMap;
  337. IndexInHeapMap index_in_heap =
  338. IndexInHeapMapHelper::build(g, index_map, index_in_heap_map_holder);
  339. typedef d_ary_heap_indirect<Vertex, 4, IndexInHeapMap, DistanceMap, Compare>
  340. MutableQueue;
  341. MutableQueue Q(distance, index_in_heap, compare);
  342. #endif // Relaxed heap
  343. detail::dijkstra_bfs_visitor<DijkstraVisitor, MutableQueue, WeightMap,
  344. PredecessorMap, DistanceMap, Combine, Compare>
  345. bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero);
  346. breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color);
  347. }
  348. // Call breadth first search
  349. template <class Graph, class DijkstraVisitor,
  350. class PredecessorMap, class DistanceMap,
  351. class WeightMap, class IndexMap, class Compare, class Combine,
  352. class DistZero, class ColorMap>
  353. inline void
  354. dijkstra_shortest_paths_no_init
  355. (const Graph& g,
  356. typename graph_traits<Graph>::vertex_descriptor s,
  357. PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
  358. IndexMap index_map,
  359. Compare compare, Combine combine, DistZero zero,
  360. DijkstraVisitor vis, ColorMap color)
  361. {
  362. dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance,
  363. weight, index_map, compare, combine,
  364. zero, vis, color);
  365. }
  366. // Initialize distances and call breadth first search with default color map
  367. template <class VertexListGraph, class SourceInputIter, class DijkstraVisitor,
  368. class PredecessorMap, class DistanceMap,
  369. class WeightMap, class IndexMap, class Compare, class Combine,
  370. class DistInf, class DistZero, typename T, typename Tag,
  371. typename Base>
  372. inline void
  373. dijkstra_shortest_paths
  374. (const VertexListGraph& g,
  375. SourceInputIter s_begin, SourceInputIter s_end,
  376. PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
  377. IndexMap index_map,
  378. Compare compare, Combine combine, DistInf inf, DistZero zero,
  379. DijkstraVisitor vis,
  380. const bgl_named_params<T, Tag, Base>&
  381. BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
  382. {
  383. boost::two_bit_color_map<IndexMap> color(num_vertices(g), index_map);
  384. dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance, weight,
  385. index_map, compare, combine, inf, zero, vis,
  386. color);
  387. }
  388. // Initialize distances and call breadth first search with default color map
  389. template <class VertexListGraph, class DijkstraVisitor,
  390. class PredecessorMap, class DistanceMap,
  391. class WeightMap, class IndexMap, class Compare, class Combine,
  392. class DistInf, class DistZero, typename T, typename Tag,
  393. typename Base>
  394. inline void
  395. dijkstra_shortest_paths
  396. (const VertexListGraph& g,
  397. typename graph_traits<VertexListGraph>::vertex_descriptor s,
  398. PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
  399. IndexMap index_map,
  400. Compare compare, Combine combine, DistInf inf, DistZero zero,
  401. DijkstraVisitor vis,
  402. const bgl_named_params<T, Tag, Base>&
  403. BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
  404. {
  405. dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight,
  406. index_map, compare, combine, inf, zero, vis);
  407. }
  408. // Initialize distances and call breadth first search
  409. template <class VertexListGraph, class SourceInputIter, class DijkstraVisitor,
  410. class PredecessorMap, class DistanceMap,
  411. class WeightMap, class IndexMap, class Compare, class Combine,
  412. class DistInf, class DistZero, class ColorMap>
  413. inline void
  414. dijkstra_shortest_paths
  415. (const VertexListGraph& g,
  416. SourceInputIter s_begin, SourceInputIter s_end,
  417. PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
  418. IndexMap index_map,
  419. Compare compare, Combine combine, DistInf inf, DistZero zero,
  420. DijkstraVisitor vis, ColorMap color)
  421. {
  422. typedef typename property_traits<ColorMap>::value_type ColorValue;
  423. typedef color_traits<ColorValue> Color;
  424. typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
  425. for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
  426. vis.initialize_vertex(*ui, g);
  427. put(distance, *ui, inf);
  428. put(predecessor, *ui, *ui);
  429. put(color, *ui, Color::white());
  430. }
  431. for (SourceInputIter it = s_begin; it != s_end; ++it) {
  432. put(distance, *it, zero);
  433. }
  434. dijkstra_shortest_paths_no_init(g, s_begin, s_end, predecessor, distance,
  435. weight, index_map, compare, combine, zero, vis,
  436. color);
  437. }
  438. // Initialize distances and call breadth first search
  439. template <class VertexListGraph, class DijkstraVisitor,
  440. class PredecessorMap, class DistanceMap,
  441. class WeightMap, class IndexMap, class Compare, class Combine,
  442. class DistInf, class DistZero, class ColorMap>
  443. inline void
  444. dijkstra_shortest_paths
  445. (const VertexListGraph& g,
  446. typename graph_traits<VertexListGraph>::vertex_descriptor s,
  447. PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
  448. IndexMap index_map,
  449. Compare compare, Combine combine, DistInf inf, DistZero zero,
  450. DijkstraVisitor vis, ColorMap color)
  451. {
  452. dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight,
  453. index_map, compare, combine, inf, zero,
  454. vis, color);
  455. }
  456. // Initialize distances and call breadth first search
  457. template <class VertexListGraph, class SourceInputIter,
  458. class DijkstraVisitor,
  459. class PredecessorMap, class DistanceMap,
  460. class WeightMap, class IndexMap, class Compare, class Combine,
  461. class DistInf, class DistZero>
  462. inline void
  463. dijkstra_shortest_paths
  464. (const VertexListGraph& g,
  465. SourceInputIter s_begin, SourceInputIter s_end,
  466. PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
  467. IndexMap index_map,
  468. Compare compare, Combine combine, DistInf inf, DistZero zero,
  469. DijkstraVisitor vis)
  470. {
  471. dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance,
  472. weight, index_map,
  473. compare, combine, inf, zero, vis,
  474. no_named_parameters());
  475. }
  476. // Initialize distances and call breadth first search
  477. template <class VertexListGraph, class DijkstraVisitor,
  478. class PredecessorMap, class DistanceMap,
  479. class WeightMap, class IndexMap, class Compare, class Combine,
  480. class DistInf, class DistZero>
  481. inline void
  482. dijkstra_shortest_paths
  483. (const VertexListGraph& g,
  484. typename graph_traits<VertexListGraph>::vertex_descriptor s,
  485. PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
  486. IndexMap index_map,
  487. Compare compare, Combine combine, DistInf inf, DistZero zero,
  488. DijkstraVisitor vis)
  489. {
  490. dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance,
  491. weight, index_map,
  492. compare, combine, inf, zero, vis);
  493. }
  494. namespace detail {
  495. // Handle defaults for PredecessorMap and
  496. // Distance Compare, Combine, Inf and Zero
  497. template <class VertexListGraph, class DistanceMap, class WeightMap,
  498. class IndexMap, class Params>
  499. inline void
  500. dijkstra_dispatch2
  501. (const VertexListGraph& g,
  502. typename graph_traits<VertexListGraph>::vertex_descriptor s,
  503. DistanceMap distance, WeightMap weight, IndexMap index_map,
  504. const Params& params)
  505. {
  506. // Default for predecessor map
  507. dummy_property_map p_map;
  508. typedef typename property_traits<DistanceMap>::value_type D;
  509. D inf = choose_param(get_param(params, distance_inf_t()),
  510. (std::numeric_limits<D>::max)());
  511. dijkstra_shortest_paths
  512. (g, s,
  513. choose_param(get_param(params, vertex_predecessor), p_map),
  514. distance, weight, index_map,
  515. choose_param(get_param(params, distance_compare_t()),
  516. std::less<D>()),
  517. choose_param(get_param(params, distance_combine_t()),
  518. closed_plus<D>(inf)),
  519. inf,
  520. choose_param(get_param(params, distance_zero_t()),
  521. D()),
  522. choose_param(get_param(params, graph_visitor),
  523. make_dijkstra_visitor(null_visitor())),
  524. params);
  525. }
  526. template <class VertexListGraph, class DistanceMap, class WeightMap,
  527. class IndexMap, class Params>
  528. inline void
  529. dijkstra_dispatch1
  530. (const VertexListGraph& g,
  531. typename graph_traits<VertexListGraph>::vertex_descriptor s,
  532. DistanceMap distance, WeightMap weight, IndexMap index_map,
  533. const Params& params)
  534. {
  535. // Default for distance map
  536. typedef typename property_traits<WeightMap>::value_type D;
  537. typename std::vector<D>::size_type
  538. n = is_default_param(distance) ? num_vertices(g) : 1;
  539. std::vector<D> distance_map(n);
  540. detail::dijkstra_dispatch2
  541. (g, s, choose_param(distance, make_iterator_property_map
  542. (distance_map.begin(), index_map,
  543. distance_map[0])),
  544. weight, index_map, params);
  545. }
  546. } // namespace detail
  547. // Named Parameter Variant
  548. template <class VertexListGraph, class Param, class Tag, class Rest>
  549. inline void
  550. dijkstra_shortest_paths
  551. (const VertexListGraph& g,
  552. typename graph_traits<VertexListGraph>::vertex_descriptor s,
  553. const bgl_named_params<Param,Tag,Rest>& params)
  554. {
  555. // Default for edge weight and vertex index map is to ask for them
  556. // from the graph. Default for the visitor is null_visitor.
  557. detail::dijkstra_dispatch1
  558. (g, s,
  559. get_param(params, vertex_distance),
  560. choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
  561. choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
  562. params);
  563. }
  564. } // namespace boost
  565. #ifdef BOOST_GRAPH_USE_MPI
  566. # include <boost/graph/distributed/dijkstra_shortest_paths.hpp>
  567. #endif
  568. #endif // BOOST_GRAPH_DIJKSTRA_HPP