BREADTH-FIRST SEARCH


In graph theory, 'breadth-first search' ('BFS') is a graph search algorithm that begins at the root node and explores all the neighboring nodes. Then for each of those nearest nodes, it explores their unexplored neighbour nodes, and so on, until it finds the goal.

Contents
How it works
Algorithm (informal)
C implementation
0)
BFS(G,i);
}
Features
Space Complexity
Time Complexity
Completeness
Optimality
Applications of BFS
Finding connected Components
Testing bipartiteness
Usage in 2D grids for computer games
See also
References
External links

How it works


BFS is a uninformed search method that aims to expand and examine all nodes of a graph systematically in search of a solution. In other words, it exhaustively searches the entire graph without considering the goal until it finds it. It does not use a heuristic.
From the standpoint of the algorithm, all child nodes obtained by expanding a node are added to a FIFO queue. In typical implementations, nodes that have not yet been examined for their neighbors are placed in some container (such as a queue or linked list) called "open" and then once examined are placed in the container "closed".
An example map of Germany with some connections between cities.
The breadth-first tree one gets when running BFS on the given map and starting in Frankfurt.
Animated example of a breadth-first search

Algorithm (informal)


# Put the ending node (the root node) in the queue.
# Pull a node from the beginning of the queue and examine it.
#
★ If the searched element is found in this node, quit the search and return a result.
#
★ Otherwise push all the (so-far-unexamined) successors (the direct child nodes) of this node into the end of the queue, if there are any.
# If the queue is empty, every node on the graph has been examined -- quit the search and return "not found".
# Repeat from Step 2.
C implementation

Algorithm of Breadth-first search:
void BFS(VLink G[], int v) {
int w;
VISIT(v); /
★ visit vertex v
★ /
visited[v] = 1; /
★ mark v as visited : 1
★ /
ADDQ(Q,v);
while(!QMPTYQ(Q)) {
v = DELQ(Q); /
★ Dequeue v
★ /
w = FIRSTADJ(G,v); /
★ Find first neighbor, return -1 if no neighbor
★ /
while(w != -1) {
if(visited[w] == 0) {
VISIT(w); /
★ visit vertex v
★ /
ADDQ(Q,w); /
★ Enqueue current visited vertext w
★ /
visited[w] = 1; /
★ mark w as visited
★ /
}
W = NEXTADJ(G,v); /
★ Find next neighbor, return -1 if no neighbor
★ /
}
}
}
Main Algorithm of apply Breadth-first search to graph G=(V,E):
void TRAVEL_BFS(VLink G[], int visited[], int n) {
int i;
for(i = 0; i < n; i ++) {
visited[i] = 0; /
★ Mark initial value as 0
★ /
}
for(i = 0; i < n; i ++)
if(visited[i] == 0)
BFS(G,i);
}
C++ implementation

This is the implementation of the above informal algorithm, where the "so-far-unexamined" is handled by the parent array. For actual C++ applications, see the Boost Graph Library.
:Suppose we have a struct:
struct Vertex {
...
std::vector out;
...
};
:and an array of vertices: (the algorithm will use the indexes of this array, to handle the vertices)
std::vector graph(vertices);
:the algorithm starts from 'start' and returns true if there is a directed path from 'start' to 'end':
bool 'BFS'(const std::vector& 'graph', int 'start', int 'end') {
std::queue next;
std::map parent;
parent[start] = -1;
next.push(start);
while (!next.empty()) {
int u = next.front();
next.pop();
''// Here is the point where you can examine the u th vertex of graph''
''// For example:''
if (u == 'end') return 'true';
for (std::vector::const_iterator j = graph[u].out.begin(); j != graph[u].out.end(); ++j) {
''// Look through neighbors.''
int v =
★ j;
if (parent.count(v) == 0) {
''// If v is unvisited.''
parent[v] = u;
next.push(v);
}
}
}
return 'false';
}
:it also stores the parents of each node, from which you can get the path.

Features


Space Complexity

Since all nodes discovered so far have to be saved, the space complexity of breadth-first search is O(|V| + |E|) where |V| is the number of nodes and |E| the number of edges in the graph. Note: another way of saying this is that it is O(B^M) where B is the maximum branching factor and M is the maximum path length of the tree. This immense demand for space is the reason why breadth-first search is impractical for larger problems.
Time Complexity

Since in the worst case breadth-first search has to consider all paths to all possible nodes the time complexity of breadth-first search is O(|V| + |E|) where |V| is the number of nodes and |E| the number of edges in the graph.
The best case of this search is o(1). It occurs when the node is found at first time.
Completeness

Breadth-first search is complete. This means that if there is a solution breadth-first search will find it regardless of the kind of graph. However, if the graph is infinite and there is no solution breadth-first search will diverge.
Optimality

For unit-step cost, breadth-first search is optimal. In general breadth-first search is not optimal since it always returns the result with the fewest edges between the start node and the goal node. If the graph is a weighted graph, and therefore has costs associated with each step, a goal next to the start does not have to be the cheapest goal available. This problem is solved by improving breadth-first search to uniform-cost search which considers the path costs. Nevertheless, if the graph is not weighted, and therefore all step costs are equal, breadth-first search will find the nearest and the best solution.

Applications of BFS


Breadth-first search can be used to solve many problems in graph theory, for example:

★ Finding all connected components in a graph.

★ Finding all nodes within one connected component

★ Copying Collection, Cheney's algorithm

★ Finding the shortest path between two nodes ''u'' and ''v'' (in an unweighted graph)

★ Testing a graph for bipartiteness

(Reverse) Cuthill–McKee mesh numbering
Finding connected Components

The set of nodes reached by a BFS are the largest connected component containing the start node.
Testing bipartiteness

BFS can be used to test bipartiteness, by starting the search at any vertex and giving alternating labels to the vertices visited during the search. That is, give label 0 to the starting vertex, 1 to all its neighbours, 0 to those neighbours' neighbours, and so on. If at any step a vertex has (visited) neighbours with the same label as itself, then the graph is not bipartite. If the search ends without such a situation occurring, then the graph is bipartite.
Usage in 2D grids for computer games

BFS has been applied to pathfinding problems in computer games, such as Real-Time Strategy games, where the graph is represented by a tilemap, and each tile in the map represents a node. Each of that node is then connected to each of its neighbour (neighbour in north, north-east, east, south-east, south, south-west, west, and north-west).
It is worth mentioning that when BFS is used in that manner, the neighbour list should be created such that north, east, south and west get priority over north-east, south-east, south-west and north-west. The reason for this is that BFS tends to start searching in a diagonal manner rather than adjacent, and the path found will not be the correct one. BFS should first search adjacent nodes, then diagonal nodes.

See also



Apriori algorithm

Depth-first search

References



Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. ''Introduction to Algorithms'', Second Edition. MIT Press and McGraw-Hill, 2001. ISBN 0-262-03293-7. Section 22.2: Breadth-first search, pp.531–539.

External links



Dictionary of Algorithms and Data Structures: breadth-first search

C++ Boost Graph Library: Breadth-First Search

Depth First and Breadth First Search: Explanation and Code

BFS Animation

Breadth First Search implementation in Python

This article provided by Wikipedia. To edit the contents of this article, click here for original source.

psst.. try this: add to faves