Registry Synced

โญ A* Search

878 words
4 min read

Reading compass

Now ยท 1. ๐ŸŽฏ Learning Objectives

โญ A* Search

1. ๐ŸŽฏ Learning Objectives

  • Trace A* with f(N)=g(N)+h(N) showing OPEN/CLOSED tables
  • Prove A* admissibility: if h(N) โ‰ค true cost, A* finds optimal path
  • Explain the dominance relation among heuristics
  • Compare A* with Best First Search and Branch & Bound
  • Identify when A* degenerates into BFS or DFS

2. ๐Ÿ“– Core Content

3.1 Intuition: Combining Cost-So-Far with Estimated-Remaining

Best First Search uses only h(N)h(N) (estimated remaining cost) โ€” it's greedy. Branch & Bound uses only g(N)g(N) (cost so far) โ€” it explores all promising partial solutions. A* combines both:
f(N)=g(N)+h(N)f(N) = g(N) + h(N)
Where:
  • g(N)g(N): Actual cost from start to N (known)
  • h(N)h(N): Estimated cost from N to goal (heuristic)
  • f(N)f(N): Estimated total cost through N

3.2 The A* Algorithm

text
AStar(initial_state, goal_test, move_gen, heuristic):
    OPEN = priority_queue()  // Ordered by f(N) = g(N) + h(N)
    OPEN.add(initial_state, h(initial_state))
    g[initial_state] = 0
    CLOSED = {}
    nodePairs = {}
    while OPEN is not empty:
        N = OPEN.extract_min()
        if goal_test(N):
            return reconstruct_path(N, nodePairs)
        CLOSED.add(N)
        for each child in move_gen(N):
            tentative_g = g[N] + cost(N, child)
            if child in CLOSED and tentative_g >= g[child]:
                continue  // Already have a better path
            if child not in OPEN or tentative_g < g[child]:
                g[child] = tentative_g
                f[child] = tentative_g + h(child)
                OPEN.add(child, f[child])
                nodePairs[child] = N
    return NO_SOLUTION

3.3 Worked Example: A* Trace

Simple route-finding graph with heuristic h(N) = straight-line distance to goal: (Diagram) h(S)=7, h(A)=6, h(B)=2, h(C)=3, h(D)=1, h(G)=0
StepOPEN (f)CLOSEDNg(N)f(N)SuccessorsNotes
0{S(7)}{}โ€”โ€”โ€”โ€”Start
1{}{S}S07A(g=1,f=7), B(g=4,f=6)Expand S
2{A(7), B(6)}{S}B46D(g=5,f=6)B has lower f
3{A(7), D(6)}{S,B}D56G(g=7,f=7)D has lower f
4{A(7), G(7)}{S,B,D}A17C(g=3,f=6), D(g=6,f=7)A has f=7
5{C(6), G(7), D(7)}{S,B,D,A}C36G(g=6,f=6)C lower f
6{G(6), G(7), D(7)}{S,B,D,A,C}G66โ€”Goal!
Wait โ€” we need to be more careful. Let me re-trace: Step 0: OPEN = {S(7)}. g(S)=0. Step 1: Pop S (f=7). Not goal. Successors: A (g=1, h=6, f=7), B (g=4, h=2, f=6). Add A and B to OPEN. Step 2: OPEN = {A(7), B(6)}. Pop B (lowest f=6). Not goal. Successors: D (g=4+1=5, h=1, f=6). Add D. Step 3: OPEN = {A(7), D(6)}. Pop D (f=6). Not goal. Successors: G (g=5+2=7, h=0, f=7). Add G. Step 4: OPEN = {A(7), G(7)}. Pop A (f=7) โ€” tie with G, but A was added earlier. Successors: C (g=1+2=3, h=3, f=6), D (g=1+5=6, h=1, f=7). D is in CLOSED, tentative_g=6 โ‰ฅ g[D]=5, so skip. Add C. Step 5: OPEN = {C(6), G(7)}. Pop C (f=6). Not goal. Successor: G (g=3+3=6, h=0, f=6). G is in OPEN with f=7. New path g=6 < old path g=7, so update G's f to 6. Step 6: OPEN = {G(6)}. Pop G (f=6). Goal! Path: S-A-C-G (cost 6). Note: A* found the optimal path S-A-C-G (total cost 6) instead of S-B-D-G (cost 7). The heuristic properly guided A* to the better path.

3.4 Admissibility

Definition: A heuristic hh is admissible if for all nodes N:
h(N)โ‰คhโˆ—(N)h(N) \leq h^*(N)
where hโˆ—(N)h^*(N) is the true minimal cost from N to the goal. Admissibility Theorem: If hh is admissible, A* returns the optimal (least-cost) solution. Proof sketch:
  1. Assume A* returns a suboptimal path with cost C>Cโˆ—C > C^* (optimal)
  2. At the point where A* terminates, there must be some node N on the optimal path in OPEN
  3. f(N)=g(N)+h(N)โ‰คg(N)+hโˆ—(N)=Cโˆ—f(N) = g(N) + h(N) \leq g(N) + h^*(N) = C^* (by admissibility)
  4. f(N)โ‰คCโˆ—<C=f(G)f(N) \leq C^* < C = f(G) (where G is the goal A* returned)
  5. So A* would have expanded N before G โ€” contradiction

3.5 Dominance

Definition: Heuristic h1h_1 dominates h2h_2 if h1(N)โ‰ฅh2(N)h_1(N) \geq h_2(N) for all nodes N (and both are admissible). A dominating heuristic is better because:
  • It provides tighter bounds
  • It prunes more nodes
  • It expands fewer states
  • A* with h1h_1 never expands more nodes than A* with h2h_2

3.6 A* Properties

PropertyValue
Optimal?Yes (with admissible heuristic)
Complete?Yes (finite state space)
Time complexityO(bd)O(b^d) worst-case
Space complexityO(bd)O(b^d) โ€” stores all generated nodes
OPEN orderf(N)=g(N)+h(N)f(N) = g(N) + h(N)

3.7 When A* Degrades

  • h(N) = 0 for all N: A* becomes BFS (or Dijkstra for weighted graphs)
  • h(N) very accurate: A* expands almost only nodes on the optimal path
  • h(N) > h(N)* (inadmissible): A* may return suboptimal solutions
  • h(N) very inaccurate: A* may expand almost as many nodes as BFS

4. ๐Ÿ“ Practice Questions

Q1: Show that the Manhattan distance heuristic is admissible for the 8-puzzle.
Answer: Manhattan distance sums the horizontal and vertical distances each tile must travel. Each move moves one tile one step, reducing Manhattan by at most 1. Therefore, the true minimum moves โ‰ฅ Manhattan distance. Hence h(N) โ‰ค h*(N) โ€” admissible. Q2: If h(N) is admissible but not consistent, what could go wrong?
Answer: A* may need to re-expand nodes (move from CLOSED back to OPEN) when a better path is found. This increases time but does not affect optimality. With a consistent heuristic, the first expansion of a node is always optimal. Q3: Does a dominating heuristic always reduce A's runtime?*
Answer: A dominating heuristic prunes more nodes (reducing expansions) but takes more time per node to compute. There is a trade-off between heuristic accuracy and computational cost. Join Discord PreviousAdmissibility & ConsistencyNextTSP Branch & Bound
Document outline

Keep your place and jump directly to a heading.

Table of contents

No note selected

Open a chapter to see its outline, backlinks, and sources here.