diff --git a/doc/subgraph.html b/doc/subgraph.html index 90c6019c..58690436 100644 --- a/doc/subgraph.html +++ b/doc/subgraph.html @@ -83,7 +83,7 @@ const int N = 6; Graph G0(N); -enum { A, B, C, D, E, F}; // for conveniently refering to vertices in G0 +enum { A, B, C, D, E, F }; // for conveniently refering to vertices in G0 Next we create two empty subgraph objects, specifying G0 as @@ -662,5 +662,5 @@ typedef property<edge_index_t, std::size_t, vertex_prop> edge_prop; typedef adjacency_list<vecS, listS, undirectedS, vertex_prop, edge_prop> Graph; -typdef subgraph<Graph> Subgraph; +typedef subgraph<Graph> Subgraph; diff --git a/include/boost/graph/dijkstra_shortest_paths.hpp b/include/boost/graph/dijkstra_shortest_paths.hpp index 10e40f82..b7bdbecd 100644 --- a/include/boost/graph/dijkstra_shortest_paths.hpp +++ b/include/boost/graph/dijkstra_shortest_paths.hpp @@ -129,7 +129,7 @@ namespace boost { template void tree_edge(Edge e, Graph& g) { - 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) m_vis.edge_relaxed(e, g); @@ -140,7 +140,7 @@ namespace boost { void gray_target(Edge e, Graph& g) { D old_distance = get(m_distance, target(e, g)); - 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); @@ -564,7 +564,7 @@ namespace boost { 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()), diff --git a/include/boost/graph/relax.hpp b/include/boost/graph/relax.hpp index e3866df4..ea9521b2 100644 --- a/include/boost/graph/relax.hpp +++ b/include/boost/graph/relax.hpp @@ -76,6 +76,37 @@ namespace boost { } else return false; } + + template + bool relax_target(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 seemingly redundant comparisons after the distance puts are to + // ensure that extra floating-point precision in x87 registers does not + // lead to relax() 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