Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -541,4 +541,4 @@ See link:../example/astar-cities.cpp[`example/astar-cities.cpp`] for an example

== Notes

[#1]#[1]# Since the visitor parameter is passed by value, if your visitor contains state then any changes to the state during the algorithm will be made to a copy of the visitor object, not the visitor object passed in. Therefore you may want the visitor to hold this state by pointer or reference.
[#1]#[1]# The visitor is taken by value, so the algorithm works on a copy. To keep state, give the visitor ordinary data members and pass it with `std::ref`. The algorithm then operates on the referenced object and its state survives the call.
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,7 @@ putting all _V - S_ vertices in the priority queue at once, but instead
only those vertices in _V - S_ that are discovered and therefore have a
distance less than infinity.

[#2]#[2]# Since the visitor parameter is passed by value, if
your visitor contains state then any changes to the state during the
algorithm will be made to a copy of the visitor object, not the visitor
object passed in. Therefore you may want the visitor to hold this state
by pointer or reference.
[#2]#[2]# The visitor is taken by value, so the algorithm works on a copy.
To keep state, give the visitor ordinary data members and pass it with
`std::ref`. The algorithm then operates on the referenced object and its
state survives the call.
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,7 @@ for an example of using Prim's algorithm.

== Notes

[#1]#[1]# Since the visitor parameter is passed by value, if
your visitor contains state then any changes to the state during the
algorithm will be made to a copy of the visitor object, not the visitor
object passed in. Therefore you may want the visitor to hold this state
by pointer or reference.
[#1]#[1]# The visitor is taken by value, so the algorithm works on a copy.
To keep state, give the visitor ordinary data members and pass it with
`std::ref`. The algorithm then operates on the referenced object and its
state survives the call.
60 changes: 36 additions & 24 deletions include/boost/graph/astar_search.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <boost/graph/relax.hpp>
#include <boost/graph/exception.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/detail/visitor_wrapper.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/graph/detail/d_ary_heap.hpp>
#include <boost/graph/property_maps/constant_property_map.hpp>
Expand Down Expand Up @@ -50,7 +51,7 @@ template < class Graph, class CostType > class astar_heuristic
typedef Vertex argument_type;
typedef CostType result_type;
astar_heuristic() {}
CostType operator()(Vertex u) { return static_cast< CostType >(0); }
CostType operator()(Vertex /*u*/) { return static_cast< CostType >(0); }
};

template < class Visitor, class Graph > struct AStarVisitorConcept
Expand Down Expand Up @@ -92,11 +93,11 @@ class astar_visitor : public bfs_visitor< Visitors >
}

private:
template < class Edge, class Graph > void tree_edge(Edge e, const Graph& g)
template < class Edge, class Graph > void tree_edge(Edge /*e*/, const Graph& /*g*/)
{
}
template < class Edge, class Graph >
void non_tree_edge(Edge e, const Graph& g)
void non_tree_edge(Edge /*e*/, const Graph& /*g*/)
{
}
};
Expand Down Expand Up @@ -144,29 +145,29 @@ namespace detail
template < class Vertex, class Graph >
void initialize_vertex(Vertex u, const Graph& g)
{
m_vis.initialize_vertex(u, g);
user_vis().initialize_vertex(u, g);
}
template < class Vertex, class Graph >
void discover_vertex(Vertex u, const Graph& g)
{
m_vis.discover_vertex(u, g);
user_vis().discover_vertex(u, g);
}
template < class Vertex, class Graph >
void examine_vertex(Vertex u, const Graph& g)
{
m_vis.examine_vertex(u, g);
user_vis().examine_vertex(u, g);
}
template < class Vertex, class Graph >
void finish_vertex(Vertex u, const Graph& g)
{
m_vis.finish_vertex(u, g);
user_vis().finish_vertex(u, g);
}
template < class Edge, class Graph >
void examine_edge(Edge e, const Graph& g)
{
if (m_compare(get(m_weight, e), m_zero))
BOOST_THROW_EXCEPTION(negative_edge());
m_vis.examine_edge(e, g);
user_vis().examine_edge(e, g);
}
template < class Edge, class Graph >
void non_tree_edge(Edge, const Graph&)
Expand All @@ -182,13 +183,13 @@ namespace detail

if (m_decreased)
{
m_vis.edge_relaxed(e, g);
user_vis().edge_relaxed(e, g);
put(m_cost, target(e, g),
m_combine(
get(m_distance, target(e, g)), m_h(target(e, g))));
}
else
m_vis.edge_not_relaxed(e, g);
user_vis().edge_not_relaxed(e, g);
}

template < class Edge, class Graph >
Expand All @@ -204,10 +205,10 @@ namespace detail
m_combine(
get(m_distance, target(e, g)), m_h(target(e, g))));
m_Q.update(target(e, g));
m_vis.edge_relaxed(e, g);
user_vis().edge_relaxed(e, g);
}
else
m_vis.edge_not_relaxed(e, g);
user_vis().edge_not_relaxed(e, g);
}

template < class Edge, class Graph >
Expand All @@ -219,16 +220,21 @@ namespace detail

if (m_decreased)
{
m_vis.edge_relaxed(e, g);
user_vis().edge_relaxed(e, g);
put(m_cost, target(e, g),
m_combine(
get(m_distance, target(e, g)), m_h(target(e, g))));
m_Q.push(target(e, g));
put(m_color, target(e, g), Color::gray());
m_vis.black_target(e, g);
user_vis().black_target(e, g);
}
else
m_vis.edge_not_relaxed(e, g);
user_vis().edge_not_relaxed(e, g);
}

auto& user_vis()
{
return ::boost::graph::detail::deref_visitor(m_vis);
}

AStarHeuristic m_h;
Expand Down Expand Up @@ -310,38 +316,40 @@ inline void astar_search_no_init_tree(const VertexListGraph& g,
null_property_map< std::pair< Distance, Vertex >, std::size_t >(),
compare);

vis.discover_vertex(s, g);
auto& vis_ref = ::boost::graph::detail::deref_visitor(vis);

vis_ref.discover_vertex(s, g);
Q.push(std::make_pair(get(cost, s), s));
while (!Q.empty())
{
Vertex v;
Distance v_rank;
boost::tie(v_rank, v) = Q.top();
Q.pop();
vis.examine_vertex(v, g);
vis_ref.examine_vertex(v, g);
BGL_FORALL_OUTEDGES_T(v, e, g, VertexListGraph)
{
Vertex w = target(e, g);
vis.examine_edge(e, g);
vis_ref.examine_edge(e, g);
Distance e_weight = get(weight, e);
if (compare(e_weight, zero))
BOOST_THROW_EXCEPTION(negative_edge());
bool decreased
= relax(e, g, weight, predecessor, distance, combine, compare);
if (decreased)
{
vis.edge_relaxed(e, g);
vis_ref.edge_relaxed(e, g);
Distance w_rank = combine(get(distance, w), h(w));
put(cost, w, w_rank);
vis.discover_vertex(w, g);
vis_ref.discover_vertex(w, g);
Q.push(std::make_pair(w_rank, w));
}
else
{
vis.edge_not_relaxed(e, g);
vis_ref.edge_not_relaxed(e, g);
}
}
vis.finish_vertex(v, g);
vis_ref.finish_vertex(v, g);
}
}

Expand All @@ -361,14 +369,16 @@ inline void astar_search(const VertexListGraph& g,

typedef typename property_traits< ColorMap >::value_type ColorValue;
typedef color_traits< ColorValue > Color;
auto& vis_ref = ::boost::graph::detail::deref_visitor(vis);

typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end;
for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
{
put(color, *ui, Color::white());
put(distance, *ui, inf);
put(cost, *ui, inf);
put(predecessor, *ui, *ui);
vis.initialize_vertex(*ui, g);
vis_ref.initialize_vertex(*ui, g);
}
put(distance, s, zero);
put(cost, s, h(s));
Expand All @@ -390,13 +400,15 @@ inline void astar_search_tree(const VertexListGraph& g,
CostZero zero)
{

auto& vis_ref = ::boost::graph::detail::deref_visitor(vis);

typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end;
for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
{
put(distance, *ui, inf);
put(cost, *ui, inf);
put(predecessor, *ui, *ui);
vis.initialize_vertex(*ui, g);
vis_ref.initialize_vertex(*ui, g);
}
put(distance, s, zero);
put(cost, s, h(s));
Expand Down
36 changes: 22 additions & 14 deletions include/boost/graph/dijkstra_shortest_paths.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <boost/graph/overloading.hpp>
#include <memory>
#include <boost/graph/detail/d_ary_heap.hpp>
#include <boost/graph/detail/visitor_wrapper.hpp>
#include <boost/graph/two_bit_color_map.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/property_map/vector_property_map.hpp>
Expand Down Expand Up @@ -97,7 +98,7 @@ class dijkstra_visitor : public bfs_visitor< Visitors >
}

private:
template < class Edge, class Graph > void tree_edge(Edge u, Graph& g) {}
template < class Edge, class Graph > void tree_edge(Edge /*u*/, Graph& /*g*/) {}
};
template < class Visitors >
dijkstra_visitor< Visitors > make_dijkstra_visitor(Visitors vis)
Expand Down Expand Up @@ -136,9 +137,9 @@ namespace detail
bool decreased = relax_target(e, g, m_weight, m_predecessor,
m_distance, m_combine, m_compare);
if (decreased)
m_vis.edge_relaxed(e, g);
user_vis().edge_relaxed(e, g);
else
m_vis.edge_not_relaxed(e, g);
user_vis().edge_not_relaxed(e, g);
}
template < class Edge, class Graph > void gray_target(Edge e, Graph& g)
{
Expand All @@ -149,27 +150,27 @@ namespace detail
if (decreased)
{
dijkstra_queue_update(m_Q, target(e, g), old_distance);
m_vis.edge_relaxed(e, g);
user_vis().edge_relaxed(e, g);
}
else
m_vis.edge_not_relaxed(e, g);
user_vis().edge_not_relaxed(e, g);
}

template < class Vertex, class Graph >
void initialize_vertex(Vertex u, Graph& g)
{
m_vis.initialize_vertex(u, g);
user_vis().initialize_vertex(u, g);
}
template < class Edge, class Graph > void non_tree_edge(Edge, Graph&) {}
template < class Vertex, class Graph >
void discover_vertex(Vertex u, Graph& g)
{
m_vis.discover_vertex(u, g);
user_vis().discover_vertex(u, g);
}
template < class Vertex, class Graph >
void examine_vertex(Vertex u, Graph& g)
{
m_vis.examine_vertex(u, g);
user_vis().examine_vertex(u, g);
}
template < class Edge, class Graph > void examine_edge(Edge e, Graph& g)
{
Expand Down Expand Up @@ -204,13 +205,18 @@ namespace detail
boost::throw_exception(negative_edge());
// End of test for negative-weight edges.

m_vis.examine_edge(e, g);
user_vis().examine_edge(e, g);
}
template < class Edge, class Graph > void black_target(Edge, Graph&) {}
template < class Vertex, class Graph >
void finish_vertex(Vertex u, Graph& g)
{
m_vis.finish_vertex(u, g);
user_vis().finish_vertex(u, g);
}

auto& user_vis()
{
return ::boost::graph::detail::deref_visitor(m_vis);
}

UniformCostVisitor m_vis;
Expand Down Expand Up @@ -250,8 +256,8 @@ namespace detail
struct vertex_property_map_generator_helper< Graph, IndexMap, Value, false >
{
typedef boost::vector_property_map< Value, IndexMap > type;
static type build(const Graph& g, const IndexMap& index,
std::unique_ptr< Value[] >& array_holder)
static type build(const Graph& /*g*/, const IndexMap& index,
std::unique_ptr< Value[] >& /*array_holder*/)
{
return boost::make_vector_property_map< Value >(index);
}
Expand Down Expand Up @@ -299,7 +305,7 @@ namespace detail
typedef boost::vector_property_map< boost::two_bit_color_type,
IndexMap >
type;
static type build(const Graph& g, const IndexMap& index)
static type build(const Graph& /*g*/, const IndexMap& index)
{
return boost::make_vector_property_map< boost::two_bit_color_type >(
index);
Expand Down Expand Up @@ -448,10 +454,12 @@ inline void dijkstra_shortest_paths(const VertexListGraph& g,
{
typedef typename property_traits< ColorMap >::value_type ColorValue;
typedef color_traits< ColorValue > Color;
auto& vis_ref = ::boost::graph::detail::deref_visitor(vis);

typename graph_traits< VertexListGraph >::vertex_iterator ui, ui_end;
for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
{
vis.initialize_vertex(*ui, g);
vis_ref.initialize_vertex(*ui, g);
put(distance, *ui, inf);
put(predecessor, *ui, *ui);
put(color, *ui, Color::white());
Expand Down
Loading
Loading