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