2 //=======================================================================
3 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
4 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
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 //=======================================================================
11 #ifndef BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP
12 #define BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP
15 Breadth First Search Algorithm (Cormen, Leiserson, and Rivest p. 470)
17 #include <boost/config.hpp>
19 #include <boost/pending/queue.hpp>
20 #include <boost/graph/graph_traits.hpp>
21 #include <boost/graph/graph_concepts.hpp>
22 #include <boost/graph/visitors.hpp>
23 #include <boost/graph/named_function_params.hpp>
27 template <class Visitor, class Graph>
28 struct BFSVisitorConcept {
30 function_requires< CopyConstructibleConcept<Visitor> >();
31 vis.initialize_vertex(u, g);
32 vis.discover_vertex(u, g);
33 vis.examine_vertex(u, g);
34 vis.examine_edge(e, g);
36 vis.non_tree_edge(e, g);
37 vis.gray_target(e, g);
38 vis.black_target(e, g);
39 vis.finish_vertex(u, g);
43 typename graph_traits<Graph>::vertex_descriptor u;
44 typename graph_traits<Graph>::edge_descriptor e;
48 template <class IncidenceGraph, class Buffer, class BFSVisitor,
50 void breadth_first_visit
51 (const IncidenceGraph& g,
52 typename graph_traits<IncidenceGraph>::vertex_descriptor s,
53 Buffer& Q, BFSVisitor vis, ColorMap color)
55 function_requires< IncidenceGraphConcept<IncidenceGraph> >();
56 typedef graph_traits<IncidenceGraph> GTraits;
57 typedef typename GTraits::vertex_descriptor Vertex;
58 typedef typename GTraits::edge_descriptor Edge;
59 function_requires< BFSVisitorConcept<BFSVisitor, IncidenceGraph> >();
60 function_requires< ReadWritePropertyMapConcept<ColorMap, Vertex> >();
61 typedef typename property_traits<ColorMap>::value_type ColorValue;
62 typedef color_traits<ColorValue> Color;
63 typename GTraits::out_edge_iterator ei, ei_end;
65 put(color, s, Color::gray()); vis.discover_vertex(s, g);
68 Vertex u = Q.top(); Q.pop(); vis.examine_vertex(u, g);
69 for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
70 Vertex v = target(*ei, g); vis.examine_edge(*ei, g);
71 ColorValue v_color = get(color, v);
72 if (v_color == Color::white()) { vis.tree_edge(*ei, g);
73 put(color, v, Color::gray()); vis.discover_vertex(v, g);
75 } else { vis.non_tree_edge(*ei, g);
76 if (v_color == Color::gray()) vis.gray_target(*ei, g);
77 else vis.black_target(*ei, g);
80 put(color, u, Color::black()); vis.finish_vertex(u, g);
82 } // breadth_first_visit
85 template <class VertexListGraph, class Buffer, class BFSVisitor,
87 void breadth_first_search
88 (const VertexListGraph& g,
89 typename graph_traits<VertexListGraph>::vertex_descriptor s,
90 Buffer& Q, BFSVisitor vis, ColorMap color)
93 typedef typename property_traits<ColorMap>::value_type ColorValue;
94 typedef color_traits<ColorValue> Color;
95 typename boost::graph_traits<VertexListGraph>::vertex_iterator i, i_end;
96 for (tie(i, i_end) = vertices(g); i != i_end; ++i) {
97 vis.initialize_vertex(*i, g);
98 put(color, *i, Color::white());
100 breadth_first_visit(g, s, Q, vis, color);
104 template <class Visitors = null_visitor>
108 bfs_visitor(Visitors vis) : m_vis(vis) { }
110 template <class Vertex, class Graph>
111 void initialize_vertex(Vertex u, Graph& g) {
112 invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex());
114 template <class Vertex, class Graph>
115 void discover_vertex(Vertex u, Graph& g) {
116 invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex());
118 template <class Vertex, class Graph>
119 void examine_vertex(Vertex u, Graph& g) {
120 invoke_visitors(m_vis, u, g, ::boost::on_examine_vertex());
122 template <class Edge, class Graph>
123 void examine_edge(Edge e, Graph& g) {
124 invoke_visitors(m_vis, e, g, ::boost::on_examine_edge());
126 template <class Edge, class Graph>
127 void tree_edge(Edge e, Graph& g) {
128 invoke_visitors(m_vis, e, g, ::boost::on_tree_edge());
130 template <class Edge, class Graph>
131 void non_tree_edge(Edge e, Graph& g) {
132 invoke_visitors(m_vis, e, g, ::boost::on_non_tree_edge());
134 template <class Edge, class Graph>
135 void gray_target(Edge e, Graph& g) {
136 invoke_visitors(m_vis, e, g, ::boost::on_gray_target());
138 template <class Edge, class Graph>
139 void black_target(Edge e, Graph& g) {
140 invoke_visitors(m_vis, e, g, ::boost::on_black_target());
142 template <class Vertex, class Graph>
143 void finish_vertex(Vertex u, Graph& g) {
144 invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex());
147 BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,bfs)
148 BOOST_GRAPH_EVENT_STUB(on_discover_vertex,bfs)
149 BOOST_GRAPH_EVENT_STUB(on_examine_vertex,bfs)
150 BOOST_GRAPH_EVENT_STUB(on_examine_edge,bfs)
151 BOOST_GRAPH_EVENT_STUB(on_tree_edge,bfs)
152 BOOST_GRAPH_EVENT_STUB(on_non_tree_edge,bfs)
153 BOOST_GRAPH_EVENT_STUB(on_gray_target,bfs)
154 BOOST_GRAPH_EVENT_STUB(on_black_target,bfs)
155 BOOST_GRAPH_EVENT_STUB(on_finish_vertex,bfs)
160 template <class Visitors>
161 bfs_visitor<Visitors>
162 make_bfs_visitor(Visitors vis) {
163 return bfs_visitor<Visitors>(vis);
165 typedef bfs_visitor<> default_bfs_visitor;
170 template <class VertexListGraph, class ColorMap, class BFSVisitor,
171 class P, class T, class R>
174 typename graph_traits<VertexListGraph>::vertex_descriptor s,
177 const bgl_named_params<P, T, R>& params)
179 typedef graph_traits<VertexListGraph> Traits;
181 typedef typename Traits::vertex_descriptor Vertex;
182 typedef boost::queue<Vertex> queue_t;
184 detail::wrap_ref<queue_t> Qref(Q);
187 choose_param(get_param(params, buffer_param_t()), Qref).ref,
191 //-------------------------------------------------------------------------
192 // Choose between default color and color parameters. Using
193 // function dispatching so that we don't require vertex index if
194 // the color default is not being used.
196 template <class ColorMap>
197 struct bfs_dispatch {
198 template <class VertexListGraph, class P, class T, class R>
201 typename graph_traits<VertexListGraph>::vertex_descriptor s,
202 const bgl_named_params<P, T, R>& params,
207 choose_param(get_param(params, graph_visitor),
208 make_bfs_visitor(null_visitor())),
214 struct bfs_dispatch<detail::error_property_not_found> {
215 template <class VertexListGraph, class P, class T, class R>
218 typename graph_traits<VertexListGraph>::vertex_descriptor s,
219 const bgl_named_params<P, T, R>& params,
220 detail::error_property_not_found)
222 std::vector<default_color_type> color_vec(num_vertices(g));
223 default_color_type c = white_color;
224 null_visitor null_vis;
228 make_iterator_property_map
230 choose_const_pmap(get_param(params, vertex_index),
231 g, vertex_index), c),
232 choose_param(get_param(params, graph_visitor),
233 make_bfs_visitor(null_vis)),
238 } // namespace detail
241 // Named Parameter Variant
242 template <class VertexListGraph, class P, class T, class R>
243 void breadth_first_search
244 (const VertexListGraph& g,
245 typename graph_traits<VertexListGraph>::vertex_descriptor s,
246 const bgl_named_params<P, T, R>& params)
248 // The graph is passed by *const* reference so that graph adaptors
249 // (temporaries) can be passed into this function. However, the
250 // graph is not really const since we may write to property maps
252 VertexListGraph& ng = const_cast<VertexListGraph&>(g);
253 typedef typename property_value< bgl_named_params<P,T,R>,
254 vertex_color_t>::type C;
255 detail::bfs_dispatch<C>::apply(ng, s, params,
256 get_param(params, vertex_color));
260 // This version does not initialize colors, user has to.
262 template <class IncidenceGraph, class P, class T, class R>
263 void breadth_first_visit
264 (const IncidenceGraph& g,
265 typename graph_traits<IncidenceGraph>::vertex_descriptor s,
266 const bgl_named_params<P, T, R>& params)
268 // The graph is passed by *const* reference so that graph adaptors
269 // (temporaries) can be passed into this function. However, the
270 // graph is not really const since we may write to property maps
272 IncidenceGraph& ng = const_cast<IncidenceGraph&>(g);
274 typedef graph_traits<IncidenceGraph> Traits;
276 typedef typename Traits::vertex_descriptor vertex_descriptor;
277 typedef boost::queue<vertex_descriptor> queue_t;
279 detail::wrap_ref<queue_t> Qref(Q);
283 choose_param(get_param(params, buffer_param_t()), Qref).ref,
284 choose_param(get_param(params, graph_visitor),
285 make_bfs_visitor(null_visitor())),
286 choose_pmap(get_param(params, vertex_color), ng, vertex_color)
292 #endif // BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP