| Graphs: | directed and undirected |
|---|---|
| Properties: | color |
| Complexity: | time: O(V + E) |
(1)
template <class VertexListGraph, class BFSVisitor>
void breadth_first_search(VertexListGraph& G,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
BFSVisitor vis);
(2)
template <class VertexListGraph, class BFSVisitor, class ColorPA>
void breadth_first_search(VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
BFSVisitor vis, ColorPA color);
(3)
template <class VertexListGraph, class BFSVisitor, class ColorPA>
void breadth_first_search(VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
Buffer& Q, BFSVisitor vis, ColorPA color)
The breadth-first search (BFS) algorithm is not really an algorithm in
the sense that it has a particular purpose. Instead BFS is more like
an algorithm pattern. One can do many different things with
BFS. For example, the BFS pattern is used in the BGL to build several
other algorithms: Dijkstra's shortest paths, Prim's Minimum Spanning
Tree and best-first search. The definition of a breadth-first
search is given in Section
.
The BGL BFS functions are highly
parameterized so that they can be used in a wide variety of places.
The way to customize the BFS algorithm to perform different operations
is to supply a visitor, which is a function object with multiple
functions. Each member function of the visitor gets invoked at special
times during the algorithm. Also, visitors can be layered on top of
each other so that one can do lots of things during a single run of
BFS. See Chapter
for more details.
Another way to customize the BFS algorithm is change the type of queue used. For instance, dijkstra_shortest_paths() uses a priority queue.
Version 1 of the algorithm takes only three arguments: the graph object, the source vertex, and a visitor to specify the actions to be taken during the graph search. The algorithm will need to use a color property which must be provided by the graph object (through a color plugin).
Version 2 of the algorithm adds a color property argument to accommodate the use of an external property accessor.
Version 3 of the algorithm is the most generalized. It adds a parameter for the queue. Version 1 and 2 of breadth_first_search() are implemented using this generalized version. This version does not initialize the color of all the vertices to white at the start of the algorithm or invoke the initialize_vertex() visitor method.
boost/graph/breadth_first_search.hpp
template <class Visitor, class Buffer, class Vertex> void operator()(Visitor v, Buffer& Q, Vertex target);}
The time complexity is O(E + V).
This example demonstrates using the BGL Breadth-first search algorithm
on the graph from Figure
.
The source code for this example is in examples/bfs_basics.cpp.
// Select the graph type we wish to use
typedef adjacency_list<vecS, undirectedS> Graph;
// Set up the vertex ID's and names
enum { r, s, t, u, v, w, x, y, N };
char name[] = { 'r', 's', 't', 'u', 'v', 'w', 'x', 'y' };
// Specify the edges in the graph
typedef pair<int,int> E;
E edge_array[] = { E(r,s), E(r,v), E(s,w), E(w,r), E(w,t),
E(w,x), E(x,t), E(t,u), E(x,y), E(u,y) };
// Create the graph object
Graph G(N, edge_array, edge_array + sizeof(edge_array)/sizeof(E));
// Some typedef's to save a little typing
typedef Graph::vertex_descriptor Vertex;
typedef std::vector<Vertex>::iterator Piter;
typedef std::vector<Graph::size_type>::iterator Iiter;
// vectors to hold color, discover time, and finish time properties
std::vector<default_color_type> color(num_vertices(G));
std::vector<Graph::size_type> dtime(num_vertices(G));
std::vector<Graph::size_type> ftime(num_vertices(G));
breadth_first_search(G, vertex(s,G),
visit_timestamp(dtime.begin(), ftime.begin()),
color.begin());
// Use std::sort to order the vertices by their discover time
vector<Graph::size_type> discover_order(N);
iota(discover_order.begin(), discover_order.end(), 0);
std::sort(discover_order.begin(), discover_order.end(),
indirect_cmp<Iiter, std::less<Graph::size_type> >(dtime.begin()));
cout << "order of discovery: ";
for (int i = 0; i < N; ++i)
cout << name[ discover_order[i] ] << " ";
vector<Graph::size_type> finish_order(N);
iota(finish_order.begin(), finish_order.end(), 0);
std::sort(finish_order.begin(), finish_order.end(),
indirect_cmp<Iiter, std::less<Graph::size_type> >(ftime.begin()));
cout << endl << "order of finish: ";
for (int i = 0; i < N; ++i)
cout << name[ finish_order[i] ] << " ";
cout << endl;
The output is:
order of discovery: s r w v t x u y order of finish: s r w v t x u y
| Copyright © 2000 | Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu) |