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