Index: dijkstra_shortest_paths.hpp =================================================================== --- dijkstra_shortest_paths.hpp (revision 92) +++ dijkstra_shortest_paths.hpp (working copy) @@ -128,21 +128,32 @@ template void tree_edge(Edge e, Graph& g) { - bool decreased = relax(e, g, m_weight, m_predecessor, m_distance, - m_combine, m_compare); - if (decreased) - m_vis.edge_relaxed(e, g); - else - m_vis.edge_not_relaxed(e, g); + relax_target_confident(e, g, m_weight, m_predecessor, m_distance + , m_combine); + m_vis.edge_relaxed(e, g); } + template void gray_target(Edge e, Graph& g) { + +#ifdef BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP D old_distance = get(m_distance, target(e, g)); +#endif +#ifdef BOOST_GRAPH_DIJKSTRA_TESTING + D old_distance = get(m_distance, target(e, g)); +#endif - bool decreased = relax(e, g, m_weight, m_predecessor, m_distance, + bool decreased = relax_target(e, g, m_weight, m_predecessor, m_distance, m_combine, m_compare); if (decreased) { - dijkstra_queue_update(m_Q, target(e, g), old_distance); + +#ifdef BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP + dijkstra_queue_update(m_Q, target(e, g), old_distance); +#endif +#ifdef BOOST_GRAPH_DIJKSTRA_TESTING + dijkstra_queue_update(m_Q, target(e, g), old_distance); +#endif + m_Q.update(target(e, g)); m_vis.edge_relaxed(e, g); } else m_vis.edge_not_relaxed(e, g); @@ -431,7 +442,7 @@ choose_param(get_param(params, distance_compare_t()), std::less()), choose_param(get_param(params, distance_combine_t()), - closed_plus(inf)), + std::plus()), inf, choose_param(get_param(params, distance_zero_t()), D()), Index: relax.hpp =================================================================== --- relax.hpp (revision 93) +++ relax.hpp (working copy) @@ -34,6 +34,55 @@ return a + b; } }; + + template + bool relax_target(const typename graph_traits::edge_descriptor& e, + const Graph& g, const WeightMap& w, + PredecessorMap& p, DistanceMap& d, + const BinaryFunction& combine, const BinaryPredicate& compare) + { + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename property_traits::value_type D; + typedef typename property_traits::value_type W; + const Vertex u = source(e, g); + const Vertex v = target(e, g); + const D& d_u = get(d, u); + const D d_v = get(d, v); + const W& w_e = get(w, e); + + // The redundant gets in the return statements are to ensure that extra + // floating-point precision in x87 registers does not lead to relax_target() + // returning true when the distance did not actually change. + if ( compare(combine(d_u, w_e), d_v) ) { + put(d, v, combine(d_u, w_e)); + if(compare(get(d, v), d_v) ) { + put(p, v, u); + return true; + }; + } + return false; + } + + template + void relax_target_confident( + const typename graph_traits::edge_descriptor& e, + const Graph& g, const WeightMap& w, PredecessorMap& p, DistanceMap& d, + const BinaryFunction& combine) + { + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename property_traits::value_type D; + typedef typename property_traits::value_type W; + const Vertex u = source(e, g); + const Vertex v = target(e, g); + const D& d_u = get(d, source(e, g)); + const W& w_e = get(w, e); + + put(d, v, combine(d_u, w_e)); + put(p, v, u); + } template