Saltar a contenido

1. Iterative Deepening Search

Iterative deepening depth-first search (IDS or IDDFS) resolves the core tension between breadth-first search (BFS) and depth-first search (DFS): BFS is optimal and complete but requires \(O(b^d)\) memory; DFS uses \(O(bd)\) memory but is neither complete (in infinite spaces) nor optimal. IDS achieves the best of both worlds — completeness, optimality (for unit step costs), and linear memory — by running a series of depth-limited DFS calls with increasing depth limits 12.

The algorithm was independently described by Korf (1985) and has since become the standard baseline for uninformed state-space search. Its iterative deepening A* (IDA*) extension applies the same idea to heuristic search.

1.1 Algorithm

1.1.1 Depth-Limited Search (DLS)

DLS is a standard DFS that stops exploring any branch once the depth of the current node reaches limit \(\ell\). It returns FOUND (solution), CUTOFF (limit was hit; solution may exist deeper), or FAILURE (no solution in this search tree).

DLS(node, goal_test, succ, limit):
  if goal_test(node.state):
    return FOUND, node.path
  if limit == 0:
    return CUTOFF, None
  cutoff_occurred = False
  for each (child, cost) in succ(node.state):
    result, path = DLS(child_node(node, child), goal_test, succ, limit - 1)
    if result == CUTOFF:
      cutoff_occurred = True
    elif result != FAILURE:
      return FOUND, path
  if cutoff_occurred:
    return CUTOFF, None
  return FAILURE, None

1.1.2 Iterative Deepening

IDS(start, goal_test, succ):
  for limit = 0, 1, 2, ...:
    result, path = DLS(make_node(start), goal_test, succ, limit)
    if result == FOUND:
      return path
    if result == FAILURE:     // no solution anywhere
      return FAILURE
    // result == CUTOFF → increase limit and retry
Variables
Symbol Meaning
\(b\) Branching factor
\(d\) Depth of shallowest goal
\(m\) Maximum depth of the search tree
\(\ell\) Current depth limit
\(N(\ell)\) Number of nodes generated at depth limit \(\ell\)

1.2 Complexity Analysis

1.2.1 Redundant Node Generation

Nodes at depth \(\leq d-1\) are generated multiple times — once per IDS iteration that reaches them. A node at depth \(k\) is generated in iterations \(\ell = k, k+1, \ldots, d\), i.e. \(d - k + 1\) times.

Total nodes generated:

\[ \begin{equation} N(d) = (d+1)b^0 + d\,b^1 + (d-1)b^2 + \cdots + 1 \cdot b^d = \sum_{k=0}^{d}(d-k+1)b^k \label{eq:ids_nodes} \end{equation} \]

For large \(b\) the sum is dominated by the last term: \(N(d) \approx b^d \cdot \tfrac{b}{b-1}\) 1.

Example \(b = 10\), \(d = 5\): BFS generates \(1 + 10 + 100 + 1000 + 10000 + 100000 = 111\,111\) nodes. IDS generates \(6 + 50 + 400 + 3000 + 20000 + 100000 = 123\,456\) nodes — only ~11 % more.

The overhead factor \(b/(b-1)\) approaches 1 as \(b\) grows, so IDS is asymptotically as efficient as BFS.

Metric BFS DFS IDS
Time \(O(b^d)\) \(O(b^m)\) \(O(b^d)\)
Space \(O(b^d)\) \(O(bm)\) \(O(bd)\)
Complete ✓ (finite) ✗ ✓ (finite)
Optimal (unit costs) ✓ ✗ ✓

1.3 Completeness and Optimality

Completeness: For any finite branching factor \(b\) and shallowest goal at depth \(d\), the IDS iteration at \(\ell = d\) will find it, as DLS with limit \(d\) is equivalent to BFS in that DLS explores every node at every depth up to \(d\). \(\square\)

Optimality (unit costs): IDS finds the shallowest goal first (at iteration \(\ell = d\)), which has the fewest edges. With uniform step costs this minimises total path cost. \(\square\)

Non-unit costs

IDS is not cost-optimal when edge costs differ. Use iterative deepening A* (IDA*) instead, which iterates on \(f = g + h\) rather than depth, or use UCS / A* directly.

1.4 IDA* (Extension)

IDA* replaces the depth limit with an \(f\)-cost threshold. Each iteration discards nodes with \(f(n) = g(n) + h(n) > \text{threshold}\); the threshold for the next iteration is the minimum \(f\)-value that was cut off. With an admissible heuristic \(h\), IDA* is optimal and uses only \(O(bd)\) space, making it the algorithm of choice for large puzzle problems (e.g. 15-puzzle, Rubik's cube).

1.5 Practical Notes

  • Visited states: Vanilla IDS does not maintain a visited set, so it may re-visit states on the same path (though not across iterations). For graph search, a per-iteration closed list can be added, but it restores \(O(b^d)\) space.
  • Cycle detection: A simple optimisation is to avoid the immediate parent on the current path (\(O(d)\) stack check).
  • Preferred over BFS/DFS when: memory is limited but optimal solutions are required, and branching factor is large.

1.6 Interactive Demo

The canvas shows IDS on a binary tree of depth 5. Each iteration sweeps through the tree up to the current limit; nodes are coloured by their status (grey = unvisited, gold = searching, blue = done for this iteration, green = goal found). Press Step to advance one DLS node at a time, or Play to animate.


  1. Stuart Russell and Peter Norvig. Artificial Intelligence: A Modern Approach. Pearson, 4th edition, 2020. ISBN 978-0-13-461099-3. ↩↩

  2. Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to Algorithms. MIT Press, 4th edition, 2022. ISBN 978-0-262-04630-5. ↩