Iterative Deepening Search (IDS) in AI (original) (raw)

Last Updated : 23 Jul, 2025

Artificial Intelligence (AI) encompasses various search algorithms to solve problems efficiently. One such algorithm, Iterative Deepening Search (IDS) also known as Iterative Deepening Depth-First Search (IDDFS), combines the advantages of both Depth-First Search (DFS) and Breadth-First Search (BFS). It is particularly useful in situations where the depth of the solution is unknown.

**In this article, we'll explore what iterative deepening search is, its significance in AI, how it works, its pros and cons, and use cases.

Table of Content

Iterative Deepening Search (IDS) is a search algorithm used in AI that blends the completeness of Breadth-First Search (BFS) with the space efficiency of Depth-First Search (DFS). IDS explores a graph or a tree by progressively increasing the depth limit with each iteration, effectively performing a series of DFS operations until the goal node is found.

This approach is particularly advantageous when the depth of the solution is unknown, and we aim to achieve both optimality and completeness without excessive memory usage.

How Iterative Deepening Search Works

The core concept of IDS revolves around repeatedly running a depth-limited DFS up to increasing depth levels. It starts with a depth limit of zero, then increments this limit iteratively. Each iteration performs a DFS search up to the current depth limit.

Here’s a step-by-step breakdown of the algorithm:

  1. **Start at the Root Node: Begin the search from the root node (or starting point).
  2. **Perform DFS with Depth Limit (L): In each iteration, perform a DFS with a depth limit L.
  3. **Increment Depth: After each iteration, increment L by 1.
  4. **Repeat: Continue this process until the goal node is found or the search space is exhausted.

Pseudo-code Example:

IterativeDeepeningSearch(root, goal)
for depth = 0 to ∞ do
result = DepthLimitedSearch(root, goal, depth)
if result == found then
return result

Implementing Iterative Deepening Search for Complex Robot Navigation

**Step 1: Import Required Libraries

We begin by importing the necessary Python libraries. We use matplotlib to visualize the grid and path, and numpy to work with the grid as a numerical array.

import matplotlib.pyplot as plt
import numpy as np

**Step 2: Define Movement Directions

We define the possible movement directions for the robot. The robot can move in four directions: up, down, left, and right. These are represented as tuples of (x, y) coordinate changes.

Define directions for robot movement (up, down, left, right)

DIRECTIONS = [(0, 1), (0, -1), (1, 0), (-1, 0)]

**Step 3: Define a Function to Check Validity of a Move

The is_valid function checks if the next position in the grid is within bounds and not an obstacle. It returns True if the move is valid, otherwise False.

Utility to check if a position is within bounds and not an obstacle

def is_valid(grid, position):
x, y = position
if 0 <= x < len(grid) and 0 <= y < len(grid[0]) and grid[x][y] != 1:
return True
return False

**Step 4: Implement the Iterative Deepening Depth-First Search (IDDFS) Algorithm

The iddfs function performs the search. It uses a helper function dls (Depth-Limited Search) to explore the grid up to a specified depth and returns the path if the goal is found.

Iterative Deepening Depth-First Search (IDDFS) Implementation

def iddfs(grid, start, goal):
def dls(node, depth, path):
if node == goal:
return path
if depth == 0:
return None
for direction in DIRECTIONS:
new_x, new_y = node[0] + direction[0], node[1] + direction[1]
next_node = (new_x, new_y)
if is_valid(grid, next_node) and next_node not in path:
result = dls(next_node, depth - 1, path + [next_node])
if result:
return result
return None

depth = 0  
while True:  
    result = dls(start, depth, [start])  
    if result:  
        return result  
    depth += 1

**Step 5: Define the Grid with Obstacles

We create a grid where 0 represents an open path and 1 represents obstacles. The grid is more complex, which makes it a challenging navigation problem for the robot.

Create a more complex grid (0: open space, 1: obstacle)

grid = [
[0, 0, 1, 0, 1, 1, 0, 0, 1, 0],
[1, 0, 1, 0, 1, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 1, 1, 1, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
[1, 1, 0, 1, 1, 1, 1, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 1, 1, 1, 0, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 0, 1, 1, 0]
]

start = (0, 0) # Starting position of the robot
goal = (9, 9) # Goal position

**Step 6: Perform the Search to Find the Path

We now call the iddfs function to perform the search from the start position to the goal position and print the found path.

Perform IDDFS

path = iddfs(grid, start, goal)
print("Path found:", path)

**Step 7: Visualize the Path

Finally, we create a function visualize_path that uses matplotlib to visualize the grid and the robot's path. The path is drawn in red, the start position is marked in green, and the goal position is marked in blue.

Visualization Code

def visualize_path(grid, path):
grid_size = (len(grid), len(grid[0]))
grid_visual = np.array(grid)

# Plot grid with obstacles  
plt.imshow(grid_visual, cmap='binary', origin='upper')

# Highlight the path with a red line  
path_x = [x for x, y in path]  
path_y = [y for x, y in path]  
plt.plot(path_y, path_x, color='red', linewidth=2, marker='o')

# Mark start and goal  
plt.text(start[1], start[0], 'S', fontsize=12, ha='center', va='center', color='green', fontweight='bold')  
plt.text(goal[1], goal[0], 'G', fontsize=12, ha='center', va='center', color='blue', fontweight='bold')

# Grid labels and layout  
plt.grid(True)  
plt.xticks(range(grid_size[1]))  
plt.yticks(range(grid_size[0]))  
plt.gca().invert_yaxis()  # To align origin at top-left corner like a typical grid

plt.title("Robot Navigation using Iterative Deepening Search (IDDFS)")  
plt.show()

Visualize the result

visualize_path(grid, path)

Complete Code: Implementing Iterative Deepening Search for Complex Robot Navigation

Python `

import matplotlib.pyplot as plt import numpy as np

Define directions for robot movement (up, down, left, right)

DIRECTIONS = [(0, 1), (0, -1), (1, 0), (-1, 0)]

Utility to check if a position is within bounds and not an obstacle

def is_valid(grid, position): x, y = position if 0 <= x < len(grid) and 0 <= y < len(grid[0]) and grid[x][y] != 1: return True return False

Iterative Deepening Depth-First Search (IDDFS) Implementation

def iddfs(grid, start, goal): def dls(node, depth, path): if node == goal: return path if depth == 0: return None for direction in DIRECTIONS: new_x, new_y = node[0] + direction[0], node[1] + direction[1] next_node = (new_x, new_y) if is_valid(grid, next_node) and next_node not in path: result = dls(next_node, depth - 1, path + [next_node]) if result: return result return None

depth = 0
while True:
    result = dls(start, depth, [start])
    if result:
        return result
    depth += 1

Create a more complex grid (0: open space, 1: obstacle)

grid = [ [0, 0, 1, 0, 1, 1, 0, 0, 1, 0], [1, 0, 1, 0, 1, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 1, 1, 1, 1, 0, 1, 1, 1, 0], [0, 0, 0, 1, 0, 0, 0, 0, 1, 0], [1, 1, 0, 1, 1, 1, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 1, 1, 1, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 0, 1, 1, 0] ]

start = (0, 0) # Starting position of the robot goal = (9, 9) # Goal position

Perform IDDFS

path = iddfs(grid, start, goal) print("Path found:", path)

Visualization Code

def visualize_path(grid, path): grid_size = (len(grid), len(grid[0])) grid_visual = np.array(grid)

# Plot grid with obstacles
plt.imshow(grid_visual, cmap='binary', origin='upper')

# Highlight the path with a red line
path_x = [x for x, y in path]
path_y = [y for x, y in path]
plt.plot(path_y, path_x, color='red', linewidth=2, marker='o')

# Mark start and goal
plt.text(start[1], start[0], 'S', fontsize=12, ha='center', va='center', color='green', fontweight='bold')
plt.text(goal[1], goal[0], 'G', fontsize=12, ha='center', va='center', color='blue', fontweight='bold')

# Grid labels and layout
plt.grid(True)
plt.xticks(range(grid_size[1]))
plt.yticks(range(grid_size[0]))
plt.gca().invert_yaxis()  # To align origin at top-left corner like a typical grid

plt.title("Robot Navigation using Iterative Deepening Search (IDDFS)")
plt.show()

Visualize the result

visualize_path(grid, path)

`

**Output:

Path found: [(0, 0), (0, 1), (1, 1), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (3, 5), (4, 5), (4, 6), (4, 7), (5, 7), (6, 7), (6, 6), (7, 6), (8, 6), (8, 7), (8, 8), (8, 9), (9, 9)]

Iterative-Deeping-Search-and-Iterative-Deeping-Depth-First-Search

IDS is designed to overcome the trade-offs between BFS and DFS. Here’s why it stands out:

Use Cases of Iterative Deepening Search in AI

IDS is particularly useful in AI applications where both memory efficiency and finding the shortest solution path are crucial. Here are a few notable use cases:

Conclusion

Iterative Deepening Search stands as a robust algorithm that bridges the gap between Depth-First Search and Breadth-First Search. Its ability to provide memory efficiency while maintaining completeness and optimality makes it an essential tool in the AI search algorithm toolkit. However, it comes with trade-offs, particularly regarding computational time. In fields like game AI and pathfinding, where depth is unknown but optimal solutions are required, IDS proves its value.