Depth Limited Search for AI
Last Updated :
23 Jul, 2025
Depth Limited Search is a key algorithm used in solving problem space concerned with artificial intelligence. But before starting it lets first understand Depth First Search which is an algorithm that explores a tree or graph by starting at the root node and exploring as far as possible along each branch before backtracking. It follows a path from the root to a leaf node then backtracks to explore other paths. This method can be inefficient when dealing with large or infinite trees as it may explore deep branches that do not contain the goal, leading to wasted time and resources.
To learn more about Depth First Search Algorithm refer to: Depth First Search or DFS for a Graph
Getting Started with Depth Limited Search (DLS)
Depth Limited Search is a modified version of DFS that imposes a limit on the depth of the search. This means that the algorithm will only explore nodes up to a certain depth effectively preventing it from going down excessively deep paths that may also lead to not reaching the goal and is computationally expensive. By setting a maximum depth limit, DLS aims to improve efficiency and ensure more manageable search times.
Example of Depth Limited Search where Set Limit = Level 2How Depth Limited Search Works
- Initialization: Begin at the root node with a specified depth limit.
- Exploration: Traverse the tree or graph, exploring each node's children.
- Depth Check: If the current depth exceeds the set limit, stop exploring that path and backtrack.
- Goal Check: If the goal node is found within the depth limit, the search is successful.
- Backtracking: If the search reaches the depth limit or a leaf node without finding the goal, backtrack and explore other branches.
Pseudocode for Depth-Limited Search
Python
def depth_limited_search(node, goal_test, limit):
if goal_test(node):
return node
elif limit == 0:
return "cutoff"
else:
cutoff_occurred = False
for child in expand(node):
result = depth_limited_search(child, goal_test, limit - 1)
if result == "cutoff":
cutoff_occurred = True
elif result != "failure":
return result
return "cutoff" if cutoff_occurred else "failure"
Here:
- The function takes node, goal_test and limit as inputs.
- If the node satisfies the goal, it returns the node as the solution.
- If the depth limit is 0, it stops and returns "cutoff" to indicate the limit was reached.
- It then expands the current node to generate child nodes. For each child, it calls itself recursively with the limit decreased by 1.
- If any child returns "cutoff" it marks that a cutoff happened.
- If any child returns a valid result (not "failure") it returns that result immediately.
- After checking all children, if any caused a cutoff, it returns "cutoff", otherwise it returns "failure" meaning no solution was found within the limit.
Applications of Depth Limited Search in AI
- Pathfinding in Robotics: DLS is employed for nonholonomic motion planning of robots in the presence of obstacles. By imposing restriction on the depth it makes the robot stop after exploring a particular depth of an area and restricting the robot from too much wandering.
- Network Routing Algorithms: A DLS can be implemented to compute paths between nodes in computer networks restricting the number of hops to prevent loops.
- Puzzle Solving in AI Systems: It can be used to solve puzzles such as the 8-puzzle or Sudoku by manipulating possible moves a fixed number of times that reduces how many steps are taken in the search.
- Game Playing: In AI for games, instead, DLS can be used to plan forward a few moves up to a certain level of depth to help decide how much effort to put into a given decision.
DFS can be used for various tasks including searching for a path between two nodes, traversing a tree or graph to visit all nodes or solving certain types of puzzles. It's often used as a building block in more complex algorithms and AI applications such as solving mazes, analyzing game states or exploring decision trees in search algorithms like minimax for games like chess or tic-tac-toe.
Finding Path in Robotics using Depth Limited Search Algorithm
Problem Setup
- Grid Environment: A 5x5 grid where 0 represents a free cell and 1 represents an obstacle.
- Initial Position: The starting position of the robot.
- Goal Position: The target position the robot needs to reach.
- Movements: The robot can move up, down, left or right.
We will be using Depth Limited Search Algorithm to resolve the problem using following steps:
Step 1: Defining the grid environment
Here, a 2D list grid represents the environment where the robot will navigate. Each cell in the grid can be either a free space (0) or an obstacle (1).
Python
# Define the grid environment with obstacles (1 indicates obstacle, 0 indicates free cell)
grid = [
[0, 0, 0, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 0]
]
Step 2: Defining Initial and Goal Positions
The initial position of the robot is defined as (0, 0) and the goal position is set to (4, 4).
Python
# Define initial and goal positions
initial_position = (0, 0)
goal_position = (4, 4)
Step 3: Defining Problem Representation
Now, a Problem class represents the problem of finding a path from the initial position to the goal position on the grid. It includes methods to check if a given state is the goal state (is_goal) and to expand a given state to find possible next states (expand).
Python
# Define problem representation
class Problem:
def __init__(self, grid, initial, goal):
self.grid = grid
self.initial_state = initial
self.goal_state = goal
def is_goal(self, state):
return state == self.goal_state
def expand(self, state):
# Define possible movements: up, down, left, right
movements = [(0, -1), (0, 1), (-1, 0), (1, 0)]
valid_moves = []
for move in movements:
new_x = state[0] + move[0]
new_y = state[1] + move[1]
# Check if the new position is within the grid and not an obstacle
if 0 <= new_x < len(self.grid) and 0 <= new_y < len(self.grid[0]) and self.grid[new_x][new_y] == 0:
valid_moves.append((new_x, new_y))
return valid_moves
Step 4: Defining Depth Limited Search (DLS) Algorithm
These functions implement the Depth Limited Search (DLS) algorithm.
depth_limited_search is the main function that initiates the search with the given depth limit. recursive_dls is a helper function that performs the recursive depth-limited search. If the goal state is found, it returns the path to that state. If the depth limit is reached, it returns "cutoff". If no solution is found within the depth limit it returns "failure".
Python
# DLS algorithm
def depth_limited_search(problem, depth_limit):
return recursive_dls(problem.initial_state, problem, depth_limit)
def recursive_dls(node, problem, depth_limit):
if problem.is_goal(node):
return [node]
elif depth_limit == 0:
return "cutoff"
else:
for child in problem.expand(node):
result = recursive_dls(child, problem, depth_limit - 1)
if result == "cutoff":
continue
elif result != "failure":
return [node] + result
return "failure"
Step 6: Creating Problem Instance
An instance of the Problem class is created with the defined grid, initial position and goal position.
Python
# Create problem instance
problem = Problem(grid, initial_position, goal_position)
Step 7: Finding Path using DLS
The DLS algorithm is applied to find a path from the initial to the goal position within a depth limit of 10. We also check the result of the search and prints the path if one is found. If no path is found within the depth limit, it prints a corresponding message.
Python
# Find path using DLS with depth limit 10
depth_limit = 10
path = depth_limited_search(problem, depth_limit)
# Output path
if path == "failure":
print("No path found within the depth limit.")
elif path == "cutoff":
print("Search terminated due to depth limit.")
else:
print("Path found:", path)
Step 8: Visualizing the Path
The function visualize_path visualizes the grid with the path found by the DLS algorithm highlighted in blue. It also marks the initial position in green and the goal position in red.
Python
import matplotlib.pyplot as plt
# Visualization code
def visualize_path(grid, path):
fig, ax = plt.subplots()
# Create a grid with the same dimensions
nrows, ncols = len(grid), len(grid[0])
ax.set_xticks([x - 0.5 for x in range(1, ncols)], minor=True)
ax.set_yticks([y - 0.5 for y in range(1, nrows)], minor=True)
ax.grid(which="minor", color="black", linestyle='-', linewidth=2)
ax.imshow(grid, cmap='Greys', interpolation='none')
# Highlight the path
if path:
for (x, y) in path:
ax.add_patch(plt.Circle((y, x), radius=0.3, color='blue'))
# Highlight initial and goal positions
ax.add_patch(plt.Circle((initial_position[1], initial_position[0]), radius=0.3, color='green'))
ax.add_patch(plt.Circle((goal_position[1], goal_position[0]), radius=0.3, color='red'))
plt.gca().invert_yaxis()
plt.title("Original Grid with DLS Path")
plt.show()
Output:
Path found: [(0, 0), (0, 1), (0, 0), (0, 1), (0, 2), (0, 3), (1, 3), (2, 3), (3, 3), (4, 3), (4, 4)]
Original Grid Discussed in the Problem Statement
Resulting Grid After applying Depth Limit Search Algorithm Advantages of Depth-Limited SearchConclusions
- Memory Efficient: Like DFS, it uses linear memory O(d) where d is the depth limit.
- Prevents Infinite Loops: Especially helpful in infinite or cyclic graphs.
- Simpler Than Other Methods: Easy to implement recursively.
- Useful in Iterative Deepening: DLS is used repeatedly with increasing depth in Iterative Deepening Search (IDS).
Limitations of Depth-Limited Search
- Incomplete: If the depth limit is too shallow, the goal won’t be found.
- Not Optimal: It does not guarantee the shortest path if multiple goal states exist.
- Requires Guessing the Right Depth: Choosing the correct depth limit is not always easy.
- Performance Drops if Goal is Far: If the goal lies just beyond the limit, DLS won’t find it and will return a cutoff.
Explore
Introduction to AI
AI Concepts
Machine Learning in AI
Robotics and AI
Generative AI
AI Practice