williamr@2: //======================================================================= williamr@2: // Copyright 2002 Indiana University. williamr@2: // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek williamr@2: // williamr@2: // Distributed under the Boost Software License, Version 1.0. (See williamr@2: // accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: //======================================================================= williamr@2: williamr@2: #ifndef BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP williamr@2: #define BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP williamr@2: williamr@2: #include williamr@2: #include williamr@2: williamr@2: // single-source shortest paths for a Directed Acyclic Graph (DAG) williamr@2: williamr@2: namespace boost { williamr@2: williamr@2: // Initalize distances and call depth first search williamr@2: template williamr@2: inline void williamr@2: dag_shortest_paths williamr@2: (const VertexListGraph& g, williamr@2: typename graph_traits::vertex_descriptor s, williamr@2: DistanceMap distance, WeightMap weight, ColorMap color, williamr@2: PredecessorMap pred, williamr@2: DijkstraVisitor vis, Compare compare, Combine combine, williamr@2: DistInf inf, DistZero zero) williamr@2: { williamr@2: typedef typename graph_traits::vertex_descriptor Vertex; williamr@2: std::vector rev_topo_order; williamr@2: rev_topo_order.reserve(num_vertices(g)); williamr@2: williamr@2: // Call 'depth_first_visit', not 'topological_sort', because we don't williamr@2: // want to traverse the entire graph, only vertices reachable from 's', williamr@2: // and 'topological_sort' will traverse everything. The logic below williamr@2: // is the same as for 'topological_sort', only we call 'depth_first_visit' williamr@2: // and 'topological_sort' calls 'depth_first_search'. williamr@2: topo_sort_visitor > > williamr@2: topo_visitor(std::back_inserter(rev_topo_order)); williamr@2: depth_first_visit(g, s, topo_visitor, color); williamr@2: williamr@2: typename graph_traits::vertex_iterator ui, ui_end; williamr@2: for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { williamr@2: put(distance, *ui, inf); williamr@2: put(pred, *ui, *ui); williamr@2: } williamr@2: williamr@2: put(distance, s, zero); williamr@2: vis.discover_vertex(s, g); williamr@2: typename std::vector::reverse_iterator i; williamr@2: for (i = rev_topo_order.rbegin(); i != rev_topo_order.rend(); ++i) { williamr@2: Vertex u = *i; williamr@2: vis.examine_vertex(u, g); williamr@2: typename graph_traits::out_edge_iterator e, e_end; williamr@2: for (tie(e, e_end) = out_edges(u, g); e != e_end; ++e) { williamr@2: vis.discover_vertex(target(*e, g), g); williamr@2: bool decreased = relax(*e, g, weight, pred, distance, williamr@2: combine, compare); williamr@2: if (decreased) williamr@2: vis.edge_relaxed(*e, g); williamr@2: else williamr@2: vis.edge_not_relaxed(*e, g); williamr@2: } williamr@2: vis.finish_vertex(u, g); williamr@2: } williamr@2: } williamr@2: williamr@2: namespace detail { williamr@2: williamr@2: // Defaults are the same as Dijkstra's algorithm williamr@2: williamr@2: // Handle Distance Compare, Combine, Inf and Zero defaults williamr@2: template williamr@2: inline void williamr@2: dag_sp_dispatch2 williamr@2: (const VertexListGraph& g, williamr@2: typename graph_traits::vertex_descriptor s, williamr@2: DistanceMap distance, WeightMap weight, ColorMap color, IndexMap id, williamr@2: DijkstraVisitor vis, const Params& params) williamr@2: { williamr@2: typedef typename property_traits::value_type D; williamr@2: dummy_property_map p_map; williamr@2: dag_shortest_paths williamr@2: (g, s, distance, weight, color, williamr@2: choose_param(get_param(params, vertex_predecessor), p_map), williamr@2: vis, williamr@2: choose_param(get_param(params, distance_compare_t()), std::less()), williamr@2: choose_param(get_param(params, distance_combine_t()), closed_plus()), williamr@2: choose_param(get_param(params, distance_inf_t()), williamr@2: (std::numeric_limits::max)()), williamr@2: choose_param(get_param(params, distance_zero_t()), williamr@2: D())); williamr@2: } williamr@2: williamr@2: // Handle DistanceMap and ColorMap defaults williamr@2: template williamr@2: inline void williamr@2: dag_sp_dispatch1 williamr@2: (const VertexListGraph& g, williamr@2: typename graph_traits::vertex_descriptor s, williamr@2: DistanceMap distance, WeightMap weight, ColorMap color, IndexMap id, williamr@2: DijkstraVisitor vis, const Params& params) williamr@2: { williamr@2: typedef typename property_traits::value_type T; williamr@2: typename std::vector::size_type n; williamr@2: n = is_default_param(distance) ? num_vertices(g) : 1; williamr@2: std::vector distance_map(n); williamr@2: n = is_default_param(color) ? num_vertices(g) : 1; williamr@2: std::vector color_map(n); williamr@2: williamr@2: dag_sp_dispatch2 williamr@2: (g, s, williamr@2: choose_param(distance, williamr@2: make_iterator_property_map(distance_map.begin(), id, williamr@2: distance_map[0])), williamr@2: weight, williamr@2: choose_param(color, williamr@2: make_iterator_property_map(color_map.begin(), id, williamr@2: color_map[0])), williamr@2: id, vis, params); williamr@2: } williamr@2: williamr@2: } // namespace detail williamr@2: williamr@2: template williamr@2: inline void williamr@2: dag_shortest_paths williamr@2: (const VertexListGraph& g, williamr@2: typename graph_traits::vertex_descriptor s, williamr@2: const bgl_named_params& params) williamr@2: { williamr@2: // assert that the graph is directed... williamr@2: null_visitor null_vis; williamr@2: detail::dag_sp_dispatch1 williamr@2: (g, s, williamr@2: get_param(params, vertex_distance), williamr@2: choose_const_pmap(get_param(params, edge_weight), g, edge_weight), williamr@2: get_param(params, vertex_color), williamr@2: choose_const_pmap(get_param(params, vertex_index), g, vertex_index), williamr@2: choose_param(get_param(params, graph_visitor), williamr@2: make_dijkstra_visitor(null_vis)), williamr@2: params); williamr@2: } williamr@2: williamr@2: } // namespace boost williamr@2: williamr@2: #endif // BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP