Uninformed search

Iterative Deepening Search (IDS)

Repeatedly dive deeper until you find the goal β€” DFS memory, BFS answers.

Final path found by Iterative Deepening Search (IDS)
On the Sydney β†’ London problem, Iterative Deepening Search finds: Sydney β†’ Colombo β†’ Istanbul β†’ London β€” total 23.5h.
β–Ά Watch Iterative Deepening Search run

The idea

Iterative Deepening Search (IDS) is an uninformed search: it uses no clues about which direction the goal is in, it just explores. It runs a depth-limited search over and over, allowing depth 0 first, then depth 1, then depth 2, and so on, restarting from the start each time. Each round digs one level deeper until the goal appears. This clever trick gives it the shallow-goal-first behavior of BFS while using only the tiny memory of DFS.

How it works

  1. Set a depth limit L = 0 (you're only allowed to look at the start node itself this round).
  2. Run a Depth-Limited Search (DFS that refuses to go deeper than L): put the start node on OPEN.
  3. Pop a node from OPEN, move it to CLOSED (it's now expanded/visited for this round), and check if it's the goal β€” if yes, stop and report success.
  4. If the popped node is still shallower than L, expand it: push its children onto OPEN to explore deeper.
  5. Keep going until OPEN is empty (this round found nothing within depth L).
  6. Increase the limit: L = L + 1, and importantly throw away CLOSED and OPEN so you start fresh from the root.
  7. Repeat the whole depth-limited search with the new, deeper limit.
  8. Because the limit grows 0, 1, 2, 3..., the first time you reach the goal it is at the shallowest possible depth β€” the fewest steps away.

See it step by step

Watch Iterative Deepening Search search a real problem β€” flying from Sydney (SYD) to London (LHR). Click Next to advance one expansion and watch OPEN, the traversal, the path and the cost update live.

Iterative Deepening Search (IDS) step
Start at Sydney. OPEN (the frontier) holds just Sydney.
Expanding
OPEN β€” frontier
CLOSED β€” traversal
Path so far
Cost so far
Step 1 / 21

OPEN, CLOSED & the data structures

OPEN (the frontier of nodes waiting to be expanded) is a stack (last-in, first-out), which is what makes each round behave like depth-first search β€” you dive down a branch before trying siblings. CLOSED (the already-expanded/visited nodes) tracks what you've handled so you don't re-process the same node within a single round. Both OPEN and CLOSED are reset to empty at the start of every new depth limit, because IDS deliberately re-explores the shallow nodes from scratch each time.

Pseudocode

function IDS(start, goal):
    for limit = 0, 1, 2, 3, ...:          # try ever-deeper limits
        result = DLS(start, goal, limit)  # fresh search each round
        if result == FOUND:
            return SUCCESS                 # goal at shallowest depth

function DLS(start, goal, limit):
    OPEN  = stack containing (start, depth=0)
    CLOSED = empty set
    while OPEN not empty:
        (node, depth) = OPEN.pop()
        if node == goal: return FOUND
        add node to CLOSED
        if depth < limit:                  # allowed to go deeper?
            for each child of node:
                if child not in CLOSED:
                    OPEN.push((child, depth + 1))
    return NOT_FOUND                        # nothing within this limit

At a glance

Complete?Yes β€” with a finite branching factor it eventually tries a limit deep enough to reach any reachable goal.
Optimal?Optimal in steps β€” because limits grow by one, the goal is first found at its minimum depth (assumes equal/unit step costs).
TimeO(b^d) β€” b = branching factor, d = goal depth; re-expanding shallow nodes only adds a constant-factor overhead, so it stays the same order as BFS.
SpaceO(b*d) β€” it only ever holds one root-to-frontier path plus its siblings, the low memory footprint of DFS.

πŸ‘ When to use it

  • The search tree is deep or even infinite and you can't afford BFS's huge memory.
  • You need the shallowest (fewest-step) goal but only have DFS-level memory.
  • The goal depth d is unknown, so you can't pick a fixed depth limit up front.
  • Step costs are all equal (unit steps); this is the classic uninformed default when memory is tight.

⚠️ Watch out for

  • It re-expands shallow nodes every round β€” that repeated work is expected, not a bug, and is cheap because deep levels dominate the count.
  • You MUST reset OPEN and CLOSED between rounds; reusing them defeats the whole restart-and-go-deeper idea.
  • It's optimal in number of steps, not in cost β€” with unequal edge costs a fewer-step path can be more expensive (use Uniform-Cost Search then).
  • On graphs with cycles, guard with the depth limit and a per-round CLOSED check so you don't loop forever down the same path.

Now see it for yourself

Open Iterative Deepening Search in the visualizer β€” step through it, pause, and watch OPEN & CLOSED change.

β–Ά Watch it run