Iterative Deepening Depth-First Search
Iterative deepening DFS is a state space/graph search strategy in which a Depth-Limited version of DFS is run repeatedly with increasing depth limits until the goal is found.
IDDFS is optimal like BFS, but uses much less memory → how??
- at each iteration, it visits the nodes in the search tree in the same order as depth-first search, but the cumulative order in which nodes are first visited is effectively breadth-first
https://www.algorithms-and-technologies.com/iterative_deepening_dfs/python
def iterative_deepening_dfs(start, target):
"""
Implementation of iterative deepening DFS (depth-first search) algorithm to find the shortest path from a start to a target node..
Given a start node, this returns the node in the tree below the start node with the target value (or null if it doesn't exist)
Runs in O(n), where n is the number of nodes in the tree, or O(b^d), where b is the branching factor and d is the depth.
:param start: the node to start the search from
:param target: the value to search for
:return: The node containing the target value or null if it doesn't exist.
"""
# Start by doing DFS with a depth of 1, keep doubling depth until we reach the "bottom" of the tree or find the node we're searching for
depth = 1
bottom_reached = False # Variable to keep track if we have reached the bottom of the tree
while not bottom_reached:
# One of the "end nodes" of the search with this depth has to still have children and set this to False again
result, bottom_reached = iterative_deepening_dfs_rec(start, target, 0, depth)
if result is not None:
# We've found the goal node while doing DFS with this max depth
return result
# We haven't found the goal node, but there are still deeper nodes to search through
depth *= 2
print("Increasing depth to " + str(depth))
# Bottom reached is True.
# We haven't found the node and there were no more nodes that still have children to explore at a higher depth.
return None
Recursive implementation.
def iterative_deepening_dfs_rec(node, target, current_depth, max_depth):
print("Visiting Node " + str(node["value"]))
if node["value"] == target:
# We have found the goal node we we're searching for
print("Found the node we're looking for!")
return node, True
if current_depth == max_depth:
print("Current maximum depth reached, returning...")
# We have reached the end for this depth...
if len(node["children"]) > 0:
# ...but we have not yet reached the bottom of the tree
return None, False
else:
return None, True
# Recurse with all children
bottom_reached = True
for i in range(len(node["children"])):
result, bottom_reached_rec = iterative_deepening_dfs_rec(node["children"][i], target, current_depth + 1,
max_depth)
if result is not None:
# We've found the goal node while going down that child
return result, True
bottom_reached = bottom_reached and bottom_reached_rec
# We've gone through all children and not found the goal node
return None, bottom_reached