Quiz 2

↔️ Breadth-First Search (BFS)

978 words
5 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# ↔️ Breadth-First Search (BFS) ## 1. 🎯 Learning Objectives By the end of this topic, you will be able to: - Trace the BFS algorithm with full OPEN/CLOSED tables showing state at every step - Explain why BFS guarantees shortest path (optimality) in unweighted graphs - Analyze BFS space complexity O(b^d) and why it...

↔️ Breadth-First Search (BFS)

1. 🎯 Learning Objectives

By the end of this topic, you will be able to:
  • Trace the BFS algorithm with full OPEN/CLOSED tables showing state at every step
  • Explain why BFS guarantees shortest path (optimality) in unweighted graphs
  • Analyze BFS space complexity O(b^d) and why it is exponential
  • Compare BFS vs DFS: when each is appropriate
  • Identify the first N nodes BFS would inspect given a state space

2. 📋 Prerequisites

PrerequisiteCourseWhy It Matters
State spaceW2 T1Understanding state representation
Queue data structureBSCS2002BFS uses FIFO queue
DFSW2 T2Comparison with BFS

3. 📖 Core Content

3.1 Intuition: Level-by-Level Exploration

Imagine a search party looking for a lost hiker. BFS is like searching in concentric circles from the last known location — first check all locations 1 km away, then all locations 2 km away, and so on. You systematically expand outward, ensuring you find the closest solution first. BFS uses a queue (FIFO — First In, First Out) for the OPEN list. It expands all nodes at depth d before expanding any node at depth d+1.

3.2 The BFS Algorithm

text
BFS(initial_state, goal_test, move_gen):
    OPEN = [initial_state]  // Queue (FIFO)
    CLOSED = {}
    nodePairs = {}
    while OPEN is not empty:
        N = dequeue(OPEN)  // Remove from front (left side)
        CLOSED.add(N)
        if goal_test(N):
            return reconstruct_path(N, nodePairs)
        successors = move_gen(N)
        for each child in successors:
            if child not in OPEN and child not in CLOSED:
                enqueue(child, OPEN)  // Add to back (right side)
                nodePairs[child] = N
    return NO_SOLUTION

3.3 Worked Example: Full BFS Trace

Consider the same graph as before: (Diagram) Goal = H. Successors in alphabetical order. BFS trace:
StepOPEN (front = left)CLOSEDNSuccessorsNotes
0[A]{}Initialize
1[]{A}AB, CNot goal. Enqueue B, C
2[B, C]{A}BD, ENot goal. Enqueue D, E
3[C, D, E]{A, B}CF, GNot goal. Enqueue F, G
4[D, E, F, G]{A, B, C}DHNot goal. Enqueue H
5[E, F, G, H]{A, B, C, D}EHE's successor H already in OPEN
6[F, G, H]{A, B, C, D, E}FGF's successor G already in OPEN
7[G, H]{A, B, C, D, E, F}GHG's successor H already in OPEN
8[H]{A, B, C, D, E, F, G}HH is goal! Path: A-B-D-H
Order of expansion: A, B, C, D, E, F, G, H Path found: A-B-D-H (length 3) Is this optimal? Yes — BFS finds shortest path (3 edges).

3.4 Worked Example 2: BFS on a Simple Tree

(Diagram) Goal = F. BFS trace:
StepOPENCLOSEDNSuccessors
0[A]{}
1[]{A}AB, C
2[B, C]{A}BD, E
3[C, D, E]{A, B}CF, G
4[D, E, F, G]{A, B, C}D
5[E, F, G]{A, B, C, D}E
6[F, G]{A, B, C, D, E}F— Goal!
Order of expansion: A, B, C, D, E, F. Path: A-C-F (length 2). Optimal!

3.5 BFS Properties

PropertyValue
Space complexityO(bd)O(b^d) — exponential
Time complexityO(bd)O(b^d) — exponential
Complete?Yes (if b and d are finite)
Optimal?Yes (shortest path in unweighted graphs)
OPEN structureQueue (FIFO)
When to useOptimality needed, small/dense state spaces

3.6 Why BFS Space Is Exponential

At depth d, there are bdb^d nodes. BFS must store all of them in OPEN/CLOSED simultaneously because they are all reachable before the goal is found. Example: b = 10, d = 10 → 10^10 nodes = 10 GB (assuming 1 byte per node — unrealistic). Real memory cost is millions of times higher because each node stores state data, parent pointers, etc. Compare:
  • BFS at depth 20, b=10: ~10^20 nodes. Impossible.
  • DFS at depth 20, b=10: ~200 nodes. Trivial.

3.7 BFS vs. DFS: Decision Table

CriterionBFSDFS
Optimal?Yes (shortest path)No
Complete?YesYes (graph-search)
SpaceO(b^d) — BADO(bd) — GOOD
TimeO(b^d)O(b^d)
Best whenShort path needed, small state spaceDeep solution, limited memory

3.8 BFS for Configuration Problems

For configuration problems (N-Queens, Sudoku), we still can use BFS, but the OPEN list grows even faster because the branching factor is typically larger (any empty square can be filled). In practice, configuration problems are solved with backtracking (DFS-style) or constraint propagation, not BFS.

4. 📐 Key Formulas / Concepts

ConceptValue
OPEN structureQueue (FIFO)
Time complexityO(bd)O(b^d)
Space complexityO(bd)O(b^d)
Complete?Yes
Optimal?Yes (shortest path)
Max OPEN sizebdb^d (at the deepest level)

5. ⚠️ Common Pitfalls

Pitfall 1: Forgetting FIFO Order

The mistake: Treating BFS OPEN like a stack and processing the most recent addition first. Correct approach: BFS processes nodes in the order they were added — oldest first, newest last.

Pitfall 2: Assuming BFS is Always Optimal

The mistake: Thinking BFS finds optimal solution in weighted graphs. Correct approach: BFS is optimal only in UNWEIGHTED graphs (where each edge cost is 1). For weighted graphs, use Dijkstra or A*.

Pitfall 3: Underestimating Memory Requirements

The mistake: Running BFS on a problem with b=10, d=100 and expecting reasonable memory. Correct approach: BFS at depth 100 with b=10 would need ~10^100 nodes — physically impossible. Use DFS or heuristic search for deep problems.

6. 📝 Practice Questions

Q1: On graph A-B, A-C, B-D, C-D (square), goal = D. Initial state A. Trace BFS.
Answer: Queue: [A]. Pop A, expand -> [B, C]. Pop B, expand -> [C, D]. Pop C, expand -> [D, D2] (C->D already in queue). Pop D -> Goal! Path: A-B-D (or A-C-D, whichever comes first depending on ordering). BFS finds shortest path (2 edges). Q2: If b=4 and goal is at depth 6, how many nodes does BFS store in OPEN at most?
Answer: At depth 6, BFS stores all nodes at that depth: 46=4,0964^6 = 4,096 nodes. Total nodes stored (all depths combined) is sum from d=0 to 6 of 4d=(471)/(41)=16,3841)/35,4614^d = (4^7 - 1)/(4 - 1) = 16,384 - 1)/3 \approx 5,461. But at exactly the moment before finding goal, OPEN contains all nodes at depth 6 = 4,096 nodes. Q3: Why can't BFS handle problems like chess (b≈35)?
Answer: BFS would need to store 35d35^d nodes. Even at modest depth d=10, that is 35102.8×101535^{10} \approx 2.8 \times 10^{15} nodes — trillions of nodes, impossible to store. Join Discord PreviousImplicit vs ExplicitNextDFID (Iterative Deepening)
Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.