# `breadth_first_search`

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 ColorMap>
      void breadth_first_search(const VertexListGraph& g,
        typename graph_traits<VertexListGraph>::vertex_descriptor s,
        BFSVisitor vis, ColorMap color);

      (3)
      template <class IncidenceGraph, class Buffer, BFSVisitor, class ColorMap>
      void breadth_first_search(const VertexListGraph& g,
        typename graph_traits<VertexListGraph>::vertex_descriptor s,
        Buffer& Q, BFSVisitor vis, ColorMap 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 Breadth-First Search.

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 as specified by BFSVisitor. 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 the bfs_visitor class and the EventVisitor concept 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.

The `ColorMap` is used by BFS to keep track of which vertices have been visited. At the beginning of the algorithm all vertices are white. As the algorithm proceeds, vertices are colored gray as they are inserted into the queue, and then colored black when they are finished and removed from 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 vertex color property).

Version 2 of the algorithm adds a color property argument to accommodate the use of an external property map.

Version 3 of the algorithm is the most generalized. It adds a parameter for the queue. 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, so that must be taken care of before calling this versin of `breadth_first_search()`.

### Where Defined

`boost/graph/breadth_first_search.hpp`

### Requirements on Types

- The type `IncidenceGraph` must be a model of IncidenceGraph.
- The type `VertexListGraph` must be a model of VertexListGraph.
- The type `BFSVisitor` must be a model of BFSVisitor.
- In version (1) of the algorithm the graph must be a model of PropertyGraph for `vertex_color_t` and the color property map for the graph must meet the same requirements as `ColorMap`.
- The type `ColorMap` must be a model of ReadWritePropertyMap. A vertex descriptor must be usable as the key type of the map, and the value type of the map must be a model of ColorValue.
- The type `Buffer` must be a model of Buffer.

### Complexity

The time complexity is O(E + V).

### Example

This example demonstrates using the BGL Breadth-first search algorithm on the graph from Figure 5. 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

### See Also

`bfs_visitor` and `depth_first_search()`

Copyright © 2000 | Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu)