diff --git a/doc/dijkstra_shortest_paths.html b/doc/dijkstra_shortest_paths.html
index fe6713c24..c8cd915d3 100644
--- a/doc/dijkstra_shortest_paths.html
+++ b/doc/dijkstra_shortest_paths.html
@@ -21,15 +21,19 @@
-// named parameter version
+//////////////////////////////////////////
+// functions that take one start vertex //
+//////////////////////////////////////////
+
+// named parameter version for a single start vertex
template <typename Graph, typename P, typename T, typename R>
-void
-dijkstra_shortest_paths(Graph& g,
- typename graph_traits<Graph>::vertex_descriptor s,
- const bgl_named_params<P, T, R>& params);
+void dijkstra_shortest_paths
+ (const Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor s,
+ const bgl_named_params<P, T, R>& params);
-// non-named parameter version
-template <typename Graph, typename DijkstraVisitor,
+// non-named parameter version for a single start vertex
+template <typename Graph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap,
typename WeightMap, typename VertexIndexMap, typename CompareFunction, typename CombineFunction,
typename DistInf, typename DistZero, typename ColorMap = default>
@@ -46,14 +50,51 @@
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistZero, class ColorMap>
-void
-dijkstra_shortest_paths_no_init
+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 = default);
+
+
+/////////////////////////////////////////////////
+// functions that take multiple start vertices //
+/////////////////////////////////////////////////
+
+// named parameter version for multiple start vertices
+template <typename Graph, typename SourceInputIter, typename P, typename T, typename R>
+void dijkstra_shortest_paths
+ (const Graph& g,
+ SourceInputIter s_begin, SourceInputIter s_end,
+ const bgl_named_params<P, T, R>& params);
+
+// non-named parameter version for multiple start vertices
+template <typename Graph, typename SourceInputIter, typename DijkstraVisitor,
+ typename PredecessorMap, typename DistanceMap,
+ typename WeightMap, typename VertexIndexMap, typename CompareFunction, typename CombineFunction,
+ typename DistInf, typename DistZero, typename ColorMap = default>
+void dijkstra_shortest_paths
+ (const Graph& g,
+ SourceInputIter s_begin, SourceInputIter s_end,
+ PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
+ VertexIndexMap index_map,
+ CompareFunction compare, CombineFunction combine, DistInf inf, DistZero zero,
+ DijkstraVisitor vis, ColorMap color = default)
+
+// version that does not initialize the property maps (except for the default color map)
+template <class Graph, class SourceInputIter, class DijkstraVisitor,
+ class PredecessorMap, class DistanceMap,
+ class WeightMap, class IndexMap, class Compare, class Combine,
+ class DistZero, class ColorMap>
+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 = default);
@@ -67,6 +108,8 @@
problem see Section Shortest-Paths
Algorithms for some background to the shortest-path problem.
+For some cases the Dijkstra algorithm can also be applied to a multiple-source
+shortest-paths problem, see the section below for more details.
@@ -186,6 +229,38 @@
Where Defined
boost/graph/dijkstra_shortest_paths.hpp
+Multiple Sources
+With some restrictions the Dijkstra algorithm can be used for the
+multiple-source shortest path problem.
+
+The following cases can be identified:
+
+Multiple Sources and Single Target
+
+Use reverse_graph to
+transfer the problem into a single-source and multiple-targets
+shortest path problem. Then you can use the Dijkstra algorithms that
+take a single source vertex as input.
+
+
+
+Alternatively, when you are only interested in the results (distance
+and route) for the source vertex closest to the target, use the
+Dijkstra algorithm that takes multiple sources as input.
+
+
+Multiple Sources and Multiple Targets
+
+You can call the Dijkstra algorithm multiple times with just one
+source vertex.
+
+
+
+Alternatively, when you are only interested in the results (distance
+and route) for the source vertex closest to a target, use the Dijkstra
+algorithm that takes multiple sources as input.
+
+
Parameters
IN: const Graph& g
@@ -206,6 +281,18 @@ Parameters
Python: The parameter is named root_vertex.
+IN: SourceInputIter s_begin, SourceInputIter s_end
+
+ Range [s_begin, s_end) of source vertices denoted by two input
+ iterators that are used for a multiple-source shortest path problem.
+ The distance to a target vertex will be calculated from the source
+ vertex in the range [s_begin, s_end) that is closest to the target,
+ the shortest path will then have this source vertex as root.
+ As a result, using these parameters you can not create an order of
+ the distances from all source vertices to a target vertex, you can
+ only retrieve the information for the closest target vertex.
+
+
Named Parameters
IN: weight_map(WeightMap w_map)
@@ -433,7 +520,9 @@ Example
See
example/dijkstra-example.cpp for an example of using Dijkstra's
-algorithm.
+algorithm and
+dijkstra-example-multiple-sources.cpp for using multiple source
+vertices.
See also
dijkstra_shortest_paths_no_color_map for a version of Dijkstra's shortest path that does not use a color map.
diff --git a/doc/dijkstra_shortest_paths_no_color_map.html b/doc/dijkstra_shortest_paths_no_color_map.html
index 05c3aec51..0aadd5ee6 100644
--- a/doc/dijkstra_shortest_paths_no_color_map.html
+++ b/doc/dijkstra_shortest_paths_no_color_map.html
@@ -21,14 +21,18 @@
-// named parameter version
+//////////////////////////////////////////
+// functions that take one start vertex //
+//////////////////////////////////////////
+
+// named parameter version for a single start vertex
template <typename Graph, typename Param, typename Tag, typename Rest>
void dijkstra_shortest_paths_no_color_map
(const Graph& graph,
typename graph_traits<Graph>::vertex_descriptor start_vertex,
const bgl_named_params& params);
-// non-named parameter version
+// non-named parameter version for a single start vertex
template <typename Graph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap,
typename WeightMap, typename VertexIndexMap, typename DistanceCompare, typename DistanceWeightCombine,
@@ -53,6 +57,44 @@
VertexIndexMap index_map,
DistanceCompare distance_compare, DistanceWeightCombine distance_weight_combine,
DistanceInfinity distance_infinity, DistanceZero distance_zero);
+
+
+/////////////////////////////////////////////////
+// functions that take multiple start vertices //
+/////////////////////////////////////////////////
+
+// named parameter version for multiple start vertices
+template <typename Graph, typename SourceInputIter, typename Param, typename Tag, typename Rest>
+void dijkstra_shortest_paths_no_color_map
+ (const Graph& graph,
+ SourceInputIter s_begin, SourceInputIter s_end,
+ const bgl_named_params& params);
+
+// non-named parameter version for multiple start vertices
+template <typename Graph, typename SourceInputIter, typename DijkstraVisitor,
+ typename PredecessorMap, typename DistanceMap,
+ typename WeightMap, typename VertexIndexMap, typename DistanceCompare, typename DistanceWeightCombine,
+ typename DistanceInfinity, typename DistanceZero>
+void dijkstra_shortest_paths_no_color_map
+ (const Graph& graph,
+ SourceInputIter s_begin, SourceInputIter s_end,
+ PredecessorMap predecessor_map, DistanceMap distance_map, WeightMap weight_map,
+ VertexIndexMap index_map,
+ DistanceCompare distance_compare, DistanceWeightCombine distance_weight_combine,
+ DistanceInfinity distance_infinity, DistanceZero distance_zero);
+
+// version that does not initialize the property maps
+template <typename Graph, typename SourceInputIter, typename DijkstraVisitor,
+ typename PredecessorMap, typename DistanceMap,
+ typename WeightMap, typename VertexIndexMap, typename DistanceCompare, typename DistanceWeightCombine,
+ typename DistanceInfinity, typename DistanceZero>
+void dijkstra_shortest_paths_no_color_map_no_init
+ (const Graph& graph,
+ SourceInputIter s_begin, SourceInputIter s_end,
+ PredecessorMap predecessor_map, DistanceMap distance_map, WeightMap weight_map,
+ VertexIndexMap index_map,
+ DistanceCompare distance_compare, DistanceWeightCombine distance_weight_combine,
+ DistanceInfinity distance_infinity, DistanceZero distance_zero);
@@ -66,6 +108,8 @@
problem see Section Shortest-Paths
Algorithms for some background to the shortest-path problem.
+For some cases the Dijkstra algorithm can also be applied to a multiple-source
+shortest-paths problem, see the section below for more details.
@@ -162,6 +206,38 @@
Where Defined
boost/graph/dijkstra_shortest_paths_no_color_map.hpp
+Multiple Sources
+With some restrictions the Dijkstra algorithm can be used for the
+multiple-source shortest path problem.
+
+The following cases can be identified:
+
+Multiple Sources and Single Target
+
+Use reverse_graph to
+transfer the problem into a single-source and multiple-targets
+shortest path problem. Then you can use the Dijkstra algorithms that
+take a single source vertex as input.
+
+
+
+Alternatively, when you are only interested in the results (distance
+and route) for the source vertex closest to the target, use the
+Dijkstra algorithm that takes multiple sources as input.
+
+
+Multiple Sources and Multiple Targets
+
+You can call the Dijkstra algorithm multiple times with just one
+source vertex.
+
+
+
+Alternatively, when you are only interested in the results (distance
+and route) for the source vertex closest to a target, use the Dijkstra
+algorithm that takes multiple sources as input.
+
+
Parameters
IN: const Graph& graph
@@ -178,6 +254,18 @@ Parameters
and the shortest paths tree will be rooted at this vertex.
+IN: SourceInputIter s_begin, SourceInputIter s_end
+
+ Range [s_begin, s_end) of source vertices denoted by two input
+ iterators that are used for a multiple-source shortest path problem.
+ The distance to a target vertex will be calculated from the source
+ vertex in the range [s_begin, s_end) that is closest to the target,
+ the shortest path will then have this source vertex as root.
+ As a result, using these parameters you can not create an order of
+ the distances from all source vertices to a target vertex, you can
+ only retrieve the information for the closest target vertex.
+
+
Named Parameters
IN: weight_map(WeightMap weight_map)
@@ -356,7 +444,10 @@ Example
See
-example/dijkstra-no-color-map-example.cpp for an example of using Dijkstra's algorithm.
+example/dijkstra-no-color-map-example.cpp for an example of using Dijkstra's algorithm
+and
+dijkstra-no-color-map-example-multiple-sources.cpp for using multiple source
+vertices.
See also
dijkstra_shortest_paths for a version of Dijkstra's shortest path that uses a color map.
diff --git a/example/Jamfile.v2 b/example/Jamfile.v2
index f1bc9d994..428806eeb 100644
--- a/example/Jamfile.v2
+++ b/example/Jamfile.v2
@@ -55,8 +55,10 @@ run dfs.cpp ;
run dfs_parenthesis.cpp ;
run dfs-example.cpp ;
run dijkstra-example.cpp ;
+run dijkstra-example-multiple-sources.cpp ;
run dijkstra-example-listS.cpp ;
run dijkstra-no-color-map-example.cpp ;
+run dijkstra-no-color-map-example-multiple-sources.cpp ;
run directed_graph.cpp ;
exe eccentricity : eccentricity.cpp ;
run edge_basics.cpp ;
diff --git a/example/dijkstra-example-multiple-sources.cpp b/example/dijkstra-example-multiple-sources.cpp
new file mode 100644
index 000000000..019b45660
--- /dev/null
+++ b/example/dijkstra-example-multiple-sources.cpp
@@ -0,0 +1,79 @@
+//=======================================================================
+// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
+// Copyright 2019 Matthias Fuchs
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+using namespace boost;
+
+int
+main(int, char *[])
+{
+ typedef adjacency_list < listS, vecS, directedS,
+ no_property, property < edge_weight_t, int > > graph_t;
+ typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor;
+ typedef std::pair Edge;
+
+ const int num_nodes = 7;
+ enum nodes { A, B, C, D, E, F, G };
+ char name[] = "ABCDEFG";
+ Edge edge_array[] = { Edge(A, C), Edge(A, B), Edge(B, A),
+ Edge(B, C), Edge(A, D), Edge(D, A), Edge(D, E), Edge(D, F), Edge(B, F),
+ Edge(F, B), Edge(F, G), Edge(G, F), Edge(G, E), Edge(E, G)
+ };
+ int weights[] = { 4, 1, 2, 3, 1, 1, 3, 2, 1, 2, 5, 1, 1, 1 };
+ int num_arcs = sizeof(edge_array) / sizeof(Edge);
+ graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
+ property_map::type weightmap = get(edge_weight, g);
+ std::vector p(num_vertices(g));
+ std::vector d(num_vertices(g));
+ vertex_descriptor start_nodes[] = { vertex(A, g), vertex(B, g) };
+
+ dijkstra_shortest_paths(g, start_nodes, start_nodes + 2,
+ predecessor_map(boost::make_iterator_property_map(p.begin(), get(boost::vertex_index, g))).
+ distance_map(boost::make_iterator_property_map(d.begin(), get(boost::vertex_index, g))));
+
+ std::cout << "distances and parents:" << std::endl;
+ graph_traits < graph_t >::vertex_iterator vi, vend;
+ for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) {
+ std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", ";
+ std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] << std::
+ endl;
+ }
+ std::cout << std::endl;
+
+ std::ofstream dot_file("figs/dijkstra-eg-multiple-sources.dot");
+
+ dot_file << "digraph D {\n"
+ << " rankdir=LR\n"
+ << " size=\"4,3\"\n"
+ << " ratio=\"fill\"\n"
+ << " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n";
+
+ graph_traits < graph_t >::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
+ graph_traits < graph_t >::edge_descriptor e = *ei;
+ graph_traits < graph_t >::vertex_descriptor
+ u = source(e, g), v = target(e, g);
+ dot_file << name[u] << " -> " << name[v]
+ << "[label=\"" << get(weightmap, e) << "\"";
+ if (p[v] == u)
+ dot_file << ", color=\"black\"";
+ else
+ dot_file << ", color=\"grey\"";
+ dot_file << "]";
+ }
+ dot_file << "}";
+ return EXIT_SUCCESS;
+}
diff --git a/example/dijkstra-no-color-map-example-multiple-sources.cpp b/example/dijkstra-no-color-map-example-multiple-sources.cpp
new file mode 100644
index 000000000..6df5f2f50
--- /dev/null
+++ b/example/dijkstra-no-color-map-example-multiple-sources.cpp
@@ -0,0 +1,83 @@
+//=======================================================================
+// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
+// Copyright 2009 Trustees of Indiana University.
+// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
+// Copyright 2019 Matthias Fuchs
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// NOTE: Based off of dijkstra-example.cpp
+//=======================================================================
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+using namespace boost;
+
+int
+main(int, char *[])
+{
+ typedef adjacency_list < listS, vecS, directedS,
+ no_property, property < edge_weight_t, int > > graph_t;
+ typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor;
+ typedef std::pair Edge;
+
+ const int num_nodes = 7;
+ enum nodes { A, B, C, D, E, F, G };
+ char name[] = "ABCDEFG";
+ Edge edge_array[] = { Edge(A, C), Edge(A, B), Edge(B, A),
+ Edge(B, C), Edge(A, D), Edge(D, A), Edge(D, E), Edge(D, F), Edge(B, F),
+ Edge(F, B), Edge(F, G), Edge(G, F), Edge(G, E), Edge(E, G)
+ };
+ int weights[] = { 4, 1, 2, 3, 1, 1, 3, 2, 1, 2, 5, 1, 1, 1 };
+ int num_arcs = sizeof(edge_array) / sizeof(Edge);
+ graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
+ property_map::type weightmap = get(edge_weight, g);
+ std::vector p(num_vertices(g));
+ std::vector d(num_vertices(g));
+ vertex_descriptor start_nodes[] = { vertex(A, g), vertex(B, g) };
+
+ dijkstra_shortest_paths_no_color_map(g, start_nodes, start_nodes + 2,
+ predecessor_map(boost::make_iterator_property_map(p.begin(), get(boost::vertex_index, g))).
+ distance_map(boost::make_iterator_property_map(d.begin(), get(boost::vertex_index, g))));
+
+ std::cout << "distances and parents:" << std::endl;
+ graph_traits < graph_t >::vertex_iterator vi, vend;
+ for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) {
+ std::cout << "distance(" << name[*vi] << ") = " << d[*vi] << ", ";
+ std::cout << "parent(" << name[*vi] << ") = " << name[p[*vi]] << std::
+ endl;
+ }
+ std::cout << std::endl;
+
+ std::ofstream dot_file("figs/dijkstra-no-color-map-eg.dot");
+
+ dot_file << "digraph D {\n"
+ << " rankdir=LR\n"
+ << " size=\"4,3\"\n"
+ << " ratio=\"fill\"\n"
+ << " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n";
+
+ graph_traits < graph_t >::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
+ graph_traits < graph_t >::edge_descriptor e = *ei;
+ graph_traits < graph_t >::vertex_descriptor
+ u = source(e, g), v = target(e, g);
+ dot_file << name[u] << " -> " << name[v]
+ << "[label=\"" << get(weightmap, e) << "\"";
+ if (p[v] == u)
+ dot_file << ", color=\"black\"";
+ else
+ dot_file << ", color=\"grey\"";
+ dot_file << "]";
+ }
+ dot_file << "}";
+ return EXIT_SUCCESS;
+}
diff --git a/include/boost/graph/dijkstra_shortest_paths.hpp b/include/boost/graph/dijkstra_shortest_paths.hpp
index 9ee2cbd6e..5d63ffd23 100644
--- a/include/boost/graph/dijkstra_shortest_paths.hpp
+++ b/include/boost/graph/dijkstra_shortest_paths.hpp
@@ -517,12 +517,12 @@ namespace boost {
// Handle defaults for PredecessorMap and
// Distance Compare, Combine, Inf and Zero
- template
+ template
inline void
dijkstra_dispatch2
(const VertexListGraph& g,
- typename graph_traits::vertex_descriptor s,
+ SourceInputIter s_begin, SourceInputIter s_end,
DistanceMap distance, WeightMap weight, IndexMap index_map,
const Params& params)
{
@@ -534,7 +534,7 @@ namespace boost {
(std::numeric_limits::max)());
dijkstra_shortest_paths
- (g, s,
+ (g, s_begin, s_end,
choose_param(get_param(params, vertex_predecessor), p_map),
distance, weight, index_map,
choose_param(get_param(params, distance_compare_t()),
@@ -549,12 +549,12 @@ namespace boost {
params);
}
- template
+ template
inline void
dijkstra_dispatch1
(const VertexListGraph& g,
- typename graph_traits::vertex_descriptor s,
+ SourceInputIter s_begin, SourceInputIter s_end,
DistanceMap distance, WeightMap weight, IndexMap index_map,
const Params& params)
{
@@ -565,31 +565,44 @@ namespace boost {
std::vector distance_map(n);
detail::dijkstra_dispatch2
- (g, s, choose_param(distance, make_iterator_property_map
- (distance_map.begin(), index_map,
- distance_map[0])),
+ (g, s_begin, s_end,
+ choose_param(distance, make_iterator_property_map
+ (distance_map.begin(), index_map,
+ distance_map[0])),
weight, index_map, params);
}
} // namespace detail
- // Named Parameter Variant
- template
+ // Named parameter version for multiple start vertices
+ template
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
- typename graph_traits::vertex_descriptor s,
+ SourceInputIter s_begin, SourceInputIter s_end,
const bgl_named_params& params)
{
// Default for edge weight and vertex index map is to ask for them
// from the graph. Default for the visitor is null_visitor.
detail::dijkstra_dispatch1
- (g, s,
+ (g, s_begin, s_end,
get_param(params, vertex_distance),
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
params);
}
+ // Named parameter version for a single start vertex
+ template
+ inline void
+ dijkstra_shortest_paths
+ (const VertexListGraph& g,
+ typename graph_traits::vertex_descriptor s,
+ const bgl_named_params& params)
+ {
+ dijkstra_shortest_paths(g, &s, &s + 1, params);
+ }
+
} // namespace boost
#include BOOST_GRAPH_MPI_INCLUDE()
diff --git a/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp b/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp
index eb96c0d88..cc87c4af4 100644
--- a/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp
+++ b/include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp
@@ -19,15 +19,16 @@
namespace boost {
- // No init version
+ // No init version for multiple start vertices
template
void dijkstra_shortest_paths_no_color_map_no_init
(const Graph& graph,
- typename graph_traits::vertex_descriptor start_vertex,
+ SourceInputIter s_begin, SourceInputIter s_end,
PredecessorMap predecessor_map,
DistanceMap distance_map,
WeightMap weight_map,
@@ -61,11 +62,15 @@ namespace boost {
index_in_heap_map_holder);
VertexQueue vertex_queue(distance_map, index_in_heap, distance_compare);
- // Add vertex to the queue
- vertex_queue.push(start_vertex);
+ // Add start vertices to the queue
+ for (SourceInputIter it = s_begin; it != s_end; ++it) {
+ vertex_queue.push(*it);
+ }
- // Starting vertex will always be the first discovered vertex
- visitor.discover_vertex(start_vertex, graph);
+ // Starting vertices will always be the first discovered vertices
+ for (SourceInputIter it = s_begin; it != s_end; ++it) {
+ visitor.discover_vertex(*it, graph);
+ }
while (!vertex_queue.empty()) {
Vertex min_vertex = vertex_queue.top();
@@ -119,13 +124,13 @@ namespace boost {
} // end while queue not empty
}
- // Full init version
+ // No init version for a single start vertex
template
- void dijkstra_shortest_paths_no_color_map
+ void dijkstra_shortest_paths_no_color_map_no_init
(const Graph& graph,
typename graph_traits::vertex_descriptor start_vertex,
PredecessorMap predecessor_map,
@@ -137,6 +142,33 @@ namespace boost {
DistanceInfinity distance_infinity,
DistanceZero distance_zero,
DijkstraVisitor visitor)
+ {
+ dijkstra_shortest_paths_no_color_map_no_init(graph,
+ &start_vertex, &start_vertex + 1,
+ predecessor_map, distance_map, weight_map, index_map,
+ distance_compare, distance_weight_combine, distance_infinity,
+ distance_zero, visitor);
+ }
+
+ // Full init version for multiple start vertices
+ template
+ void dijkstra_shortest_paths_no_color_map
+ (const Graph& graph,
+ SourceInputIter s_begin, SourceInputIter s_end,
+ PredecessorMap predecessor_map,
+ DistanceMap distance_map,
+ WeightMap weight_map,
+ VertexIndexMap index_map,
+ DistanceCompare distance_compare,
+ DistanceWeightCombine distance_weight_combine,
+ DistanceInfinity distance_infinity,
+ DistanceZero distance_zero,
+ DijkstraVisitor visitor)
{
// Initialize vertices
BGL_FORALL_VERTICES_T(current_vertex, graph, Graph) {
@@ -149,26 +181,55 @@ namespace boost {
put(predecessor_map, current_vertex, current_vertex);
}
- // Set distance for start_vertex to zero
- put(distance_map, start_vertex, distance_zero);
+ // Set distance for start vertices to zero
+ for (SourceInputIter it = s_begin; it != s_end; ++it) {
+ put(distance_map, *it, distance_zero);
+ }
// Pass everything on to the no_init version
dijkstra_shortest_paths_no_color_map_no_init(graph,
- start_vertex, predecessor_map, distance_map, weight_map,
- index_map, distance_compare, distance_weight_combine,
- distance_infinity, distance_zero, visitor);
+ s_begin, s_end, predecessor_map, distance_map,
+ weight_map, index_map, distance_compare,
+ distance_weight_combine, distance_infinity, distance_zero,
+ visitor);
+ }
+
+ // Full init version for a single start vertex
+ template
+ void dijkstra_shortest_paths_no_color_map
+ (const Graph& graph,
+ typename graph_traits::vertex_descriptor start_vertex,
+ PredecessorMap predecessor_map,
+ DistanceMap distance_map,
+ WeightMap weight_map,
+ VertexIndexMap index_map,
+ DistanceCompare distance_compare,
+ DistanceWeightCombine distance_weight_combine,
+ DistanceInfinity distance_infinity,
+ DistanceZero distance_zero,
+ DijkstraVisitor visitor)
+ {
+ dijkstra_shortest_paths_no_color_map(graph,
+ &start_vertex, &start_vertex + 1,
+ predecessor_map, distance_map, weight_map, index_map,
+ distance_compare, distance_weight_combine, distance_infinity,
+ distance_zero, visitor);
}
namespace detail {
// Handle defaults for PredecessorMap, DistanceCompare,
// DistanceWeightCombine, DistanceInfinity and DistanceZero
- template
+ template
inline void
dijkstra_no_color_map_dispatch2
(const Graph& graph,
- typename graph_traits::vertex_descriptor start_vertex,
+ SourceInputIter s_begin, SourceInputIter s_end,
DistanceMap distance_map, WeightMap weight_map,
VertexIndexMap index_map, const Params& params)
{
@@ -180,7 +241,7 @@ namespace boost {
choose_param(get_param(params, distance_inf_t()),
(std::numeric_limits::max)());
dijkstra_shortest_paths_no_color_map
- (graph, start_vertex,
+ (graph, s_begin, s_end,
choose_param(get_param(params, vertex_predecessor), predecessor_map),
distance_map, weight_map, index_map,
choose_param(get_param(params, distance_compare_t()),
@@ -194,12 +255,12 @@ namespace boost {
make_dijkstra_visitor(null_visitor())));
}
- template
+ template
inline void
dijkstra_no_color_map_dispatch1
(const Graph& graph,
- typename graph_traits::vertex_descriptor start_vertex,
+ SourceInputIter s_begin, SourceInputIter s_end,
DistanceMap distance_map, WeightMap weight_map,
IndexMap index_map, const Params& params)
{
@@ -211,31 +272,44 @@ namespace boost {
std::vector default_distance_map(vertex_count);
detail::dijkstra_no_color_map_dispatch2
- (graph, start_vertex, choose_param(distance_map,
+ (graph, s_begin, s_end, choose_param(distance_map,
make_iterator_property_map(default_distance_map.begin(), index_map,
default_distance_map[0])),
weight_map, index_map, params);
}
} // namespace detail
- // Named parameter version
- template
+ // Named parameter version for multiple start vertices
+ template
inline void
dijkstra_shortest_paths_no_color_map
(const Graph& graph,
- typename graph_traits::vertex_descriptor start_vertex,
+ SourceInputIter s_begin, SourceInputIter s_end,
const bgl_named_params& params)
{
// Default for edge weight and vertex index map is to ask for them
// from the graph. Default for the visitor is null_visitor.
detail::dijkstra_no_color_map_dispatch1
- (graph, start_vertex,
+ (graph, s_begin, s_end,
get_param(params, vertex_distance),
choose_const_pmap(get_param(params, edge_weight), graph, edge_weight),
choose_const_pmap(get_param(params, vertex_index), graph, vertex_index),
params);
}
+ // Named parameter version for a single start vertex
+ template
+ inline void
+ dijkstra_shortest_paths_no_color_map
+ (const Graph& graph,
+ typename graph_traits::vertex_descriptor start_vertex,
+ const bgl_named_params& params)
+ {
+ dijkstra_shortest_paths_no_color_map(graph,
+ &start_vertex, &start_vertex + 1, params);
+ }
+
} // namespace boost
#endif // BOOST_GRAPH_DIJKSTRA_NO_COLOR_MAP_HPP
diff --git a/test/dijkstra_no_color_map_compare.cpp b/test/dijkstra_no_color_map_compare.cpp
index 89a4bcc70..b33a6324e 100644
--- a/test/dijkstra_no_color_map_compare.cpp
+++ b/test/dijkstra_no_color_map_compare.cpp
@@ -74,6 +74,102 @@ void run_dijkstra_test(const Graph& graph)
no_color_map_vertex_double_map.begin()));
}
+template
+void run_dijkstra_multiple_start_vertices_test(const Graph& graph)
+{
+ /*
+ Calculate from two start vertices A and B (MULTIPLE).
+ Also calculate with a single start vertex A (CALC_A) and B (CALC_B).
+ When the distance from A to a target X is shorter than from B to X
+ compare MULTIPLE with CALC_B and vice versa.
+ In case distance A -> X and B -> X are equal check that any of
+ CALC_A/CALC_B matches MULTIPLE.
+ */
+ using namespace boost;
+
+ // Set up property maps
+ typedef typename graph_traits::vertex_descriptor vertex_t;
+
+ typedef typename std::map vertex_map_t;
+ typedef associative_property_map predecessor_map_t;
+ vertex_map_t vertex_predecessor_map_1,
+ vertex_predecessor_map_2,
+ vertex_predecessor_map_12,
+ vertex_predecessor_map_12_color;
+ predecessor_map_t predecessors_1(vertex_predecessor_map_1),
+ predecessors_2(vertex_predecessor_map_2),
+ predecessors_12(vertex_predecessor_map_12),
+ predecessors_12_color(vertex_predecessor_map_12_color);
+
+ typedef typename std::map vertex_double_map_t;
+ typedef associative_property_map distance_map_t;
+ vertex_double_map_t vertex_distance_map_1,
+ vertex_distance_map_2,
+ vertex_distance_map_12,
+ vertex_distance_map_12_color;
+ distance_map_t distances_1(vertex_distance_map_1),
+ distances_2(vertex_distance_map_2),
+ distances_12(vertex_distance_map_12),
+ distances_12_color(vertex_distance_map_12_color);
+
+ // calculate from two start vertices
+ vertex_t start_vertex_1 = vertex(0, graph);
+ vertex_t start_vertex_2 = vertex(num_vertices(graph) / 2, graph);
+ std::vector start_vertices;
+ start_vertices.push_back(start_vertex_1);
+ start_vertices.push_back(start_vertex_2);
+
+ // Run dijkstra algorithms
+ dijkstra_shortest_paths_no_color_map(
+ graph, start_vertex_1,
+ predecessor_map(predecessors_1)
+ .distance_map(distances_1));
+ dijkstra_shortest_paths_no_color_map(
+ graph, start_vertex_2,
+ predecessor_map(predecessors_2)
+ .distance_map(distances_2));
+ dijkstra_shortest_paths_no_color_map(
+ graph, start_vertices.begin(), start_vertices.end(),
+ predecessor_map(predecessors_12)
+ .distance_map(distances_12));
+ dijkstra_shortest_paths(
+ graph, start_vertices.begin(), start_vertices.end(),
+ predecessor_map(predecessors_12_color)
+ .distance_map(distances_12_color));
+
+ // Check the results
+ typedef typename vertex_map_t::const_iterator vertex_map_t_iter;
+ vertex_map_t_iter it_pred1 = vertex_predecessor_map_1.begin(),
+ it_pred2 = vertex_predecessor_map_2.begin(),
+ it_pred12 = vertex_predecessor_map_12.begin(),
+ it_pred12_color = vertex_predecessor_map_12_color.begin();
+
+ typedef typename vertex_double_map_t::const_iterator vertex_double_map_t_iter;
+ vertex_double_map_t_iter it_dist1 = vertex_distance_map_1.begin(),
+ it_dist2 = vertex_distance_map_2.begin(),
+ it_dist12 = vertex_distance_map_12.begin(),
+ it_dist12_color = vertex_distance_map_12_color.begin();
+
+ while (it_pred1 != vertex_predecessor_map_1.end()) {
+ BOOST_CHECK(*it_pred12 == *it_pred12_color);
+ BOOST_CHECK(*it_dist12 == *it_dist12_color);
+
+ if (it_dist1->second < it_dist2->second) {
+ BOOST_CHECK(*it_pred1 == *it_pred12);
+ BOOST_CHECK(*it_dist1 == *it_dist12);
+ } else if (it_dist2->second < it_dist1->second) {
+ BOOST_CHECK(*it_pred2 == *it_pred12);
+ BOOST_CHECK(*it_dist2 == *it_dist12);
+ } else {
+ BOOST_CHECK(*it_pred1 == *it_pred12 || *it_pred2 == *it_pred12);
+ BOOST_CHECK(*it_dist1 == *it_dist12);
+ }
+
+ ++it_pred1, ++it_pred2, ++it_pred12, ++it_pred12_color;
+ ++it_dist1, ++it_dist2, ++it_dist12, ++it_dist12_color;
+ }
+}
+
int test_main(int argc, char* argv[])
{
using namespace boost;
@@ -120,6 +216,7 @@ int test_main(int argc, char* argv[])
" vertices and " << num_edges(graph) << " edges " << std::endl;
run_dijkstra_test(graph);
+ run_dijkstra_multiple_start_vertices_test(graph);
return 0;
}