Iterative Deepening Search (IDS) is a search strategy in artificial intelligence that combines the benefits of Depth-First Search (DFS) and Breadth-First Search (BFS). It’s particularly useful for searching large state spaces, like in puzzles or pathfinding problems, where the depth of the solution isn’t known in advance. Below, I’ll explain IDS, how it works, its properties, and provide a clear example.
IDS is a heuristic-uninformed search algorithm that repeatedly applies DFS with increasing depth limits until the goal is found or the entire search space is explored. It starts with a depth limit of 0, explores all nodes up to that depth, then increases the limit to 1, 2, and so on, restarting the DFS each time. This iterative process ensures that IDS finds the shallowest goal node (like BFS) while using the memory efficiency of DFS.
IterativeDeepeningSearch(root, goal)
for depth = 0 to ∞ do
result = DepthLimitedSearch(root, goal, depth)
if result == found then
return result
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)
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)
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)]