Open In App

Depth Limited Search for AI

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
14 Likes
Like
Report

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.

depth_limited_search
Example of Depth Limited Search where Set Limit = Level 2

How Depth Limited Search Works

  1. Initialization: Begin at the root node with a specified depth limit.
  2. Exploration: Traverse the tree or graph, exploring each node's children.
  3. Depth Check: If the current depth exceeds the set limit, stop exploring that path and backtrack.
  4. Goal Check: If the goal node is found within the depth limit, the search is successful.
  5. Backtracking: If the search reaches the depth limit or a leaf node without finding the goal, backtrack and explore other branches.
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

  1. 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.
  2. Network Routing Algorithms: A DLS can be implemented to compute paths between nodes in computer networks restricting the number of hops to prevent loops.
  3. 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.
  4. 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)]

download
Original Grid Discussed in the Problem Statement
download-(3)
Resulting Grid After applying Depth Limit Search Algorithm

Advantages of Depth-Limited SearchConclusions

  1. Memory Efficient: Like DFS, it uses linear memory O(d) where d is the depth limit.
  2. Prevents Infinite Loops: Especially helpful in infinite or cyclic graphs.
  3. Simpler Than Other Methods: Easy to implement recursively.
  4. Useful in Iterative Deepening: DLS is used repeatedly with increasing depth in Iterative Deepening Search (IDS).
  1. Incomplete: If the depth limit is too shallow, the goal won’t be found.
  2. Not Optimal: It does not guarantee the shortest path if multiple goal states exist.
  3. Requires Guessing the Right Depth: Choosing the correct depth limit is not always easy.
  4. 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