dijkstra_shortest_paths_no_color_map.hpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. //=======================================================================
  2. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  3. // Copyright 2009 Trustees of Indiana University.
  4. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Michael Hansen
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //=======================================================================
  10. #ifndef BOOST_GRAPH_DIJKSTRA_NO_COLOR_MAP_HPP
  11. #define BOOST_GRAPH_DIJKSTRA_NO_COLOR_MAP_HPP
  12. #include <boost/pending/indirect_cmp.hpp>
  13. #include <boost/graph/relax.hpp>
  14. #include <boost/graph/detail/d_ary_heap.hpp>
  15. #include <boost/graph/dijkstra_shortest_paths.hpp>
  16. #include <boost/graph/iteration_macros.hpp>
  17. namespace boost {
  18. // No init version
  19. template <typename Graph, typename DijkstraVisitor,
  20. typename PredecessorMap, typename DistanceMap,
  21. typename WeightMap, typename VertexIndexMap,
  22. typename DistanceCompare, typename DistanceWeightCombine,
  23. typename DistanceInfinity, typename DistanceZero>
  24. void dijkstra_shortest_paths_no_color_map_no_init
  25. (const Graph& graph,
  26. typename graph_traits<Graph>::vertex_descriptor start_vertex,
  27. PredecessorMap predecessor_map,
  28. DistanceMap distance_map,
  29. WeightMap weight_map,
  30. VertexIndexMap index_map,
  31. DistanceCompare distance_compare,
  32. DistanceWeightCombine distance_weight_combine,
  33. DistanceInfinity distance_infinity,
  34. DistanceZero distance_zero,
  35. DijkstraVisitor visitor)
  36. {
  37. typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
  38. typedef typename property_traits<DistanceMap>::value_type Distance;
  39. typedef indirect_cmp<DistanceMap, DistanceCompare> DistanceIndirectCompare;
  40. DistanceIndirectCompare
  41. distance_indirect_compare(distance_map, distance_compare);
  42. // Default - use d-ary heap (d = 4)
  43. typedef
  44. detail::vertex_property_map_generator<Graph, VertexIndexMap, std::size_t>
  45. IndexInHeapMapHelper;
  46. typedef typename IndexInHeapMapHelper::type IndexInHeapMap;
  47. typedef
  48. d_ary_heap_indirect<Vertex, 4, IndexInHeapMap, DistanceMap, DistanceCompare>
  49. VertexQueue;
  50. boost::scoped_array<std::size_t> index_in_heap_map_holder;
  51. IndexInHeapMap index_in_heap =
  52. IndexInHeapMapHelper::build(graph, index_map,
  53. index_in_heap_map_holder);
  54. VertexQueue vertex_queue(distance_map, index_in_heap, distance_compare);
  55. // Add vertex to the queue
  56. vertex_queue.push(start_vertex);
  57. // Starting vertex will always be the first discovered vertex
  58. visitor.discover_vertex(start_vertex, graph);
  59. while (!vertex_queue.empty()) {
  60. Vertex min_vertex = vertex_queue.top();
  61. vertex_queue.pop();
  62. visitor.examine_vertex(min_vertex, graph);
  63. // Check if any other vertices can be reached
  64. Distance min_vertex_distance = get(distance_map, min_vertex);
  65. if (!distance_compare(min_vertex_distance, distance_infinity)) {
  66. // This is the minimum vertex, so all other vertices are unreachable
  67. return;
  68. }
  69. // Examine neighbors of min_vertex
  70. BGL_FORALL_OUTEDGES_T(min_vertex, current_edge, graph, Graph) {
  71. visitor.examine_edge(current_edge, graph);
  72. // Check if the edge has a negative weight
  73. if (distance_compare(get(weight_map, current_edge), distance_zero)) {
  74. boost::throw_exception(negative_edge());
  75. }
  76. // Extract the neighboring vertex and get its distance
  77. Vertex neighbor_vertex = target(current_edge, graph);
  78. Distance neighbor_vertex_distance = get(distance_map, neighbor_vertex);
  79. bool is_neighbor_undiscovered =
  80. !distance_compare(neighbor_vertex_distance, distance_infinity);
  81. // Attempt to relax the edge
  82. bool was_edge_relaxed = relax_target(current_edge, graph, weight_map,
  83. predecessor_map, distance_map,
  84. distance_weight_combine, distance_compare);
  85. if (was_edge_relaxed) {
  86. visitor.edge_relaxed(current_edge, graph);
  87. if (is_neighbor_undiscovered) {
  88. visitor.discover_vertex(neighbor_vertex, graph);
  89. vertex_queue.push(neighbor_vertex);
  90. } else {
  91. vertex_queue.update(neighbor_vertex);
  92. }
  93. } else {
  94. visitor.edge_not_relaxed(current_edge, graph);
  95. }
  96. } // end out edge iteration
  97. visitor.finish_vertex(min_vertex, graph);
  98. } // end while queue not empty
  99. }
  100. // Full init version
  101. template <typename Graph, typename DijkstraVisitor,
  102. typename PredecessorMap, typename DistanceMap,
  103. typename WeightMap, typename VertexIndexMap,
  104. typename DistanceCompare, typename DistanceWeightCombine,
  105. typename DistanceInfinity, typename DistanceZero>
  106. void dijkstra_shortest_paths_no_color_map
  107. (const Graph& graph,
  108. typename graph_traits<Graph>::vertex_descriptor start_vertex,
  109. PredecessorMap predecessor_map,
  110. DistanceMap distance_map,
  111. WeightMap weight_map,
  112. VertexIndexMap index_map,
  113. DistanceCompare distance_compare,
  114. DistanceWeightCombine distance_weight_combine,
  115. DistanceInfinity distance_infinity,
  116. DistanceZero distance_zero,
  117. DijkstraVisitor visitor)
  118. {
  119. // Initialize vertices
  120. BGL_FORALL_VERTICES_T(current_vertex, graph, Graph) {
  121. visitor.initialize_vertex(current_vertex, graph);
  122. // Default all distances to infinity
  123. put(distance_map, current_vertex, distance_infinity);
  124. // Default all vertex predecessors to the vertex itself
  125. put(predecessor_map, current_vertex, current_vertex);
  126. }
  127. // Set distance for start_vertex to zero
  128. put(distance_map, start_vertex, distance_zero);
  129. // Pass everything on to the no_init version
  130. dijkstra_shortest_paths_no_color_map_no_init(graph,
  131. start_vertex, predecessor_map, distance_map, weight_map,
  132. index_map, distance_compare, distance_weight_combine,
  133. distance_infinity, distance_zero, visitor);
  134. }
  135. namespace detail {
  136. // Handle defaults for PredecessorMap, DistanceCompare,
  137. // DistanceWeightCombine, DistanceInfinity and DistanceZero
  138. template <typename Graph, typename DistanceMap, typename WeightMap,
  139. typename VertexIndexMap, typename Params>
  140. inline void
  141. dijkstra_no_color_map_dispatch2
  142. (const Graph& graph,
  143. typename graph_traits<Graph>::vertex_descriptor start_vertex,
  144. DistanceMap distance_map, WeightMap weight_map,
  145. VertexIndexMap index_map, const Params& params)
  146. {
  147. // Default for predecessor map
  148. dummy_property_map predecessor_map;
  149. typedef typename property_traits<DistanceMap>::value_type DistanceType;
  150. DistanceType inf =
  151. choose_param(get_param(params, distance_inf_t()),
  152. (std::numeric_limits<DistanceType>::max)());
  153. dijkstra_shortest_paths_no_color_map
  154. (graph, start_vertex,
  155. choose_param(get_param(params, vertex_predecessor), predecessor_map),
  156. distance_map, weight_map, index_map,
  157. choose_param(get_param(params, distance_compare_t()),
  158. std::less<DistanceType>()),
  159. choose_param(get_param(params, distance_combine_t()),
  160. std::plus<DistanceType>()),
  161. inf,
  162. choose_param(get_param(params, distance_zero_t()),
  163. DistanceType()),
  164. choose_param(get_param(params, graph_visitor),
  165. make_dijkstra_visitor(null_visitor())));
  166. }
  167. template <typename Graph, typename DistanceMap, typename WeightMap,
  168. typename IndexMap, typename Params>
  169. inline void
  170. dijkstra_no_color_map_dispatch1
  171. (const Graph& graph,
  172. typename graph_traits<Graph>::vertex_descriptor start_vertex,
  173. DistanceMap distance_map, WeightMap weight_map,
  174. IndexMap index_map, const Params& params)
  175. {
  176. // Default for distance map
  177. typedef typename property_traits<WeightMap>::value_type DistanceType;
  178. typename std::vector<DistanceType>::size_type
  179. vertex_count = is_default_param(distance_map) ? num_vertices(graph) : 1;
  180. std::vector<DistanceType> default_distance_map(vertex_count);
  181. detail::dijkstra_no_color_map_dispatch2
  182. (graph, start_vertex, choose_param(distance_map,
  183. make_iterator_property_map(default_distance_map.begin(), index_map,
  184. default_distance_map[0])),
  185. weight_map, index_map, params);
  186. }
  187. } // namespace detail
  188. // Named parameter version
  189. template <typename Graph, typename Param, typename Tag, typename Rest>
  190. inline void
  191. dijkstra_shortest_paths_no_color_map
  192. (const Graph& graph,
  193. typename graph_traits<Graph>::vertex_descriptor start_vertex,
  194. const bgl_named_params<Param, Tag, Rest>& params)
  195. {
  196. // Default for edge weight and vertex index map is to ask for them
  197. // from the graph. Default for the visitor is null_visitor.
  198. detail::dijkstra_no_color_map_dispatch1
  199. (graph, start_vertex,
  200. get_param(params, vertex_distance),
  201. choose_const_pmap(get_param(params, edge_weight), graph, edge_weight),
  202. choose_const_pmap(get_param(params, vertex_index), graph, vertex_index),
  203. params);
  204. }
  205. } // namespace boost
  206. #endif // BOOST_GRAPH_DIJKSTRA_NO_COLOR_MAP_HPP