Breadth First Search (BFS) is an uninformed search algorithm used to traverse or search graph and tree structures. It explores nodes level by level, visiting all nodes at the current depth before moving to the next depth level.
- Uses a queue to maintain the order of node expansion.
- Does not require heuristic information.
- Guarantees the shortest path in unweighted graphs.
Need for Breadth-First Search
- Some problems require finding the shortest path between states.
- A systematic exploration strategy is needed to avoid missing solutions.
- Many AI problems involve searching large state spaces represented as graphs or trees.
- BFS provides a complete search method when all actions have equal cost.
Key Characteristics
- First-In-First-Out (FIFO): BFS uses a queue that follows the FIFO principle. Nodes discovered earlier are expanded before nodes discovered later, ensuring level-by-level exploration.
- Level-Order Exploration: The algorithm visits all nodes at one depth level before moving to the next level, guaranteeing systematic traversal of the search space.
- Early Goal Test: The goal condition is checked as soon as a new node is generated. This helps terminate the search immediately when a solution is found.
- Complete Search: BFS is complete, meaning it will find a solution if one exists in a finite search space.
- Optimal for Unweighted Graphs: Since nodes are explored in order of increasing depth, BFS always finds the shortest path when all actions have equal cost.
Working
- Initialization: The search begins from the start node, which is added to the queue and marked as visited.
- Node Expansion: The node at the front of the queue is removed and selected for processing.
- Neighbor Exploration: All unvisited neighboring nodes are discovered, marked as visited, and added to the queue.
- Level-by-Level Traversal: Nodes are expanded in the order they were discovered, ensuring all nodes at the current depth are explored first.
- Goal Checking: The algorithm checks whether the current node satisfies the goal condition during traversal.
- Termination: The search stops when the goal is found or when all reachable nodes have been explored.

Implementation
Consider a robot placed in an environment that needs to reach a goal location. The robot explores all neighboring positions level by level using Breadth-First Search (BFS). The following implementation demonstrates how BFS helps the robot find the shortest path while avoiding obstacles.

Step 1: Robot Starts at the Initial Position
The robot begins at node R, which acts as the root node of the search tree. Since BFS follows the FIFO principle, the starting node is marked as visited and added to the queue.

class Node:
def __init__(self, state, parent=None, action=None):
self.state = state
self.parent = parent
self.action = action
Step 2: Expand the Starting Node
The robot removes R from the queue and explores all valid neighboring positions.

To generate valid neighboring cells, we define the GridProblem class.
from collections import deque
class GridProblem:
def __init__(self, initial_state, goal_state, grid):
self.initial_state = initial_state
self.goal_state = goal_state
self.grid = grid
def is_goal(self, state):
return state == self.goal_state
Step 3: Generate Successor Nodes
After expanding R, the robot discovers valid successor positions.

The following method checks whether a cell is valid and not blocked by an obstacle.
def is_valid_cell(self, row, col):
return (
0 <= row < len(self.grid)
and 0 <= col < len(self.grid[0])
and self.grid[col][row] == 0
)
Step 4: Enqueue Newly Discovered Positions
The discovered positions are marked as visited and added to the rear of the queue.

Queue: [S, E]
The robot continues exploring positions in FIFO order.
The following method generates all valid neighboring positions.
def expand(self, node):
row, col = node.state
children = []
for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
new_row, new_col = row + dr, col + dc
if self.is_valid_cell(new_row, new_col):
child_state = (new_row, new_col)
child_node = Node(child_state, parent=node)
children.append(child_node)
return children
Step 5: Continue Exploring Level by Level
The next node is removed from the queue and expanded. BFS continues exploring all nodes at the current depth before moving to deeper levels.

This behavior guarantees that the first path found to the goal is the shortest path in an unweighted environment.
To reconstruct the final route after reaching the goal, define the following helper functions.
def reconstruct_path(node):
path = []
while node:
path.append(node.state)
node = node.parent
return list(reversed(path))
def print_complete_path(path):
for step, point in enumerate(path):
print(f"Step {step}: {point}")
Step 6: Perform BFS Traversal
Now we apply the Breadth-First Search algorithm to navigate the robot through the environment.
breadth_first_search(problem)
Step 7: Example Usage
The robot starts at (0,0) and attempts to reach the goal at (6,0) while avoiding obstacles.
Grid with Obstacles:
Robot (0,0) | Block | (2,0) | (3,0) | Block | (5,0) | Goal |
(0,1) | Block | (2,1) | (3,1) | Block | (5,1) | (6,1) |
(0,2) | (1,2) | (2,2) | (3,2) | Block | (5,2) | (6,2) |
(0,3) | (1,3) | Block | (3,4) | Block | (5,3) | (6,3) |
(0,4) | (1,4) | Block | (3,5) | (4,4) | (5,4) | (6,4) |
(0,5) | (1,5) | Block | (3,6) | (4,5) | (5,5) | (6,5) |
(0,6) | (1,6) | Block | (3,6) | (4,6) | (5,6) | (6,6) |
"""
1 : Denotes the obstacles
0 : Empty space or a non-obstacle cell in the grid
"""
grid = [
[0, 1, 0, 0, 1, 0, 0],
[0, 1, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0]
]
initial_state = (0, 0)
goal_state = (6, 0)
problem = GridProblem(initial_state, goal_state, grid)
solution_node = breadth_first_search(problem)
print('!! Reached the Goal!!' if solution_node else None)
if solution_node:
print("Solution found!")
solution_path = reconstruct_path(solution_node)
print("Complete Path:")
print_complete_path(solution_path)
else:
print("No solution found")
Output:
The robot explores neighboring cells level by level until it discovers a path to the goal.
!! Reached the Goal!!
Solution found!
Complete Path:
Step 0: (0, 0)
Step 1: (0, 1)
Step 2: (0, 2)
Step 3: (1, 2)
Step 4: (2, 2)
Step 5: (3, 2)
Step 6: (3, 3)
Step 7: (3, 4)
Step 8: (4, 4)
Step 9: (5, 4)
Step 10: (6, 4)
Step 11: (6, 3)
Step 12: (6, 2)
Step 13: (6, 1)
Step 14: (6, 0)
The robot successfully reaches the goal node (6,0). Since BFS explores all nodes level by level, the path obtained is the shortest available path from the starting position to the goal.

You can get the full code from here.
Applications
- Web Crawling: Search engines use BFS to discover and index web pages systematically.
- Social Network Analysis: Helps find user connections, mutual friends, and degrees of separation.
- Game AI: Used for character navigation, pathfinding, and puzzle solving.
- State Space Search: Explores possible states to find solutions in AI problems.
- Network Broadcasting: Enables efficient propagation of messages across connected networks.
Advantages
- Always finds the shortest path in unweighted graphs.
- Easy to understand and implement with a queue.
- Used in web crawling, social networks, AI, etc.
- Explores nodes level by level without missing any.
Limitations
- Needs to store all nodes at each level.
- Explores many shallow nodes before deep ones.
- Doesn't handle edge weights; Dijkstra’s is better.