Algorithm Search⌘K

Proofs: Best-first search

These are the human proofs of Best-first search, at full length.

Best-first search is sound and stops on finite spaces, and with f = g + h for an admissible h it returns a cheapest path full

This proof shows: correctness, termination.

We use the pseudocode of the page, with action costs c≥0c \ge 0. A node is live while it is the node stored in reached for its state. Line L6 skips each popped node that is not live. A node is expanded when it passes line L6 and line L7 and reaches line L8.

Fact 1 (each node is a path). Each node nn is the end of a chain of parent pointers that spells a path s0=x0,x1,…,xk=n.states_0 = x_0, x_1, \ldots, x_k = n.\mathrm{state} of the state space, with n.gn.g the sum of the costs of its actions and n.depth=kn.\mathrm{depth} = k. This holds for the root of line L1, and line L9 adds one action of cost cc to the path of the parent, cc to gg and 11 to the depth. □\square

Fact 2 (stored costs decrease). For each state ss, the value reached[s].g\mathrm{reached}[s].g only decreases strictly over time, because line L11 overwrites the entry only after line L10 found a strictly smaller gg. A state never leaves reached.

Fact 3 (live nodes). Each node in the chain of parents of a pushed node was pushed, at line L2 or line L12. A live node is in the frontier or was expanded: it was pushed when it became live, and a live node that is popped is either returned at line L7 or expanded.

Theorem 1 (soundness). If the search returns (P,g)(P, g), then PP is a path from s0s_0 to a goal state and gg is its cost.

Proof. The search returns only at line L7, with PP the path of a node nn whose state passes IS-GOAL, and g=n.gg = n.g. By Fact 1, PP is a path from s0s_0 to n.staten.\mathrm{state} with cost n.gn.g. □\square

Lemma 2 (no repeated state). Each node pushed at line L12 is a path without a repeated state. Two pushed nodes never have the same path.

Proof. Suppose a pushed node mm has the path x0,…,xkx_0, \ldots, x_k with xi=xjx_i = x_j for some i<ji < j. Let pip_i and pjp_j be the nodes of the prefixes that end at positions ii and jj. By Fact 3 both were pushed, and pip_i was pushed before pjp_j was created, since pjp_j descends from pip_i. From the push of pip_i on, reached[xi].g≤pi.g\mathrm{reached}[x_i].g \le p_i.g by Fact 2. The cycle from position ii to position jj has cost at least 00, so pj.g≥pi.g≥reached[xj].gp_j.g \ge p_i.g \ge \mathrm{reached}[x_j].g when pjp_j was created. Then the test at line L10 failed, and pjp_j was not pushed, a contradiction. If two pushed nodes had the same path, they would have the same gg, and the second would fail the test at line L10 in the same way. □\square

Theorem 3 (finite spaces, any ff). If finitely many states can be reached from s0s_0, the search stops for every evaluation function ff. If it returns failure, then no goal state can be reached from s0s_0.

Proof. A finite space has finitely many paths from s0s_0 without a repeated state. By Lemma 2, each of them is pushed at most once and no other path is pushed. So the number of pushes is finite. Each iteration pops a node, so the loop stops.

Suppose the search returns failure at line L13, so the frontier is empty. By Fact 3, the live node of each state in reached was expanded. Let s0=y0,y1,…,yrs_0 = y_0, y_1, \ldots, y_r be a path to a goal state yry_r. We show by induction that each yiy_i is in reached. The state y0y_0 is in reached from line L3. If yiy_i is in reached, its live node was expanded, so line L10 was run for a child with state yi+1y_{i+1}, and after it yi+1y_{i+1} was in reached, which by Fact 2 it never leaves. So yry_r is in reached, and its live node was expanded. But a live node of a goal state is returned at line L7 and never expanded. This contradiction shows that no goal is reachable. □\square

Lemma 4 (a good node in the frontier). Let f(n)=n.g+h(n.state)f(n) = n.g + h(n.\mathrm{state}), where hh is admissible: 0≤h(s)≤h∗(s)0 \le h(s) \le h^*(s) for each state ss, with h∗(s)h^*(s) the least cost of a path from ss to a goal. Let π=x0,…,xr\pi = x_0, \ldots, x_r be a path from s0s_0 to a goal state xrx_r with cost CC. At the start of each iteration of line L4, if the search has not yet returned, the frontier holds a live node qq with f(q)≤Cf(q) \le C.

Proof. Write CjC_j for the cost of the prefix x0,…,xjx_0, \ldots, x_j. Call xjx_j covered when xjx_j is in reached and reached[xj].g≤Cj\mathrm{reached}[x_j].g \le C_j. By Fact 2, a covered state stays covered. The state x0x_0 is covered, since its root node has g=0=C0g = 0 = C_0. Let jj be the largest index such that x0,…,xjx_0, \ldots, x_j are all covered, and let qq be the live node of xjx_j, so q.g≤Cjq.g \le C_j.

If j<rj < r and qq was expanded, then line L10 was run for a child with state xj+1x_{j+1} and g=q.g+c(xj,xj+1)≤Cj+1g = q.g + c(x_j, x_{j+1}) \le C_{j+1}, and afterwards reached[xj+1].g≤Cj+1\mathrm{reached}[x_{j+1}].g \le C_{j+1}. Then xj+1x_{j+1} is covered, against the choice of jj. If j=rj = r, then qq is a live node of a goal state, and it was not expanded, by line L7. So in both cases qq was not expanded, and by Fact 3 it is in the frontier. The rest of π\pi is a path from xjx_j to a goal with cost C−CjC - C_j, so h(xj)≤h∗(xj)≤C−Cjh(x_j) \le h^*(x_j) \le C - C_j, and

f(q)=q.g+h(xj)≤Cj+(C−Cj)=C.□f(q) = q.g + h(x_j) \le C_j + (C - C_j) = C. \qquad \square

Theorem 5 (optimality for f=g+hf = g + h). Let f=g+hf = g + h with hh admissible. If the search returns (P,g)(P, g), then g=C∗g = C^*, the infimum of the costs of the paths from s0s_0 to a goal.

Proof. Let the search return the node nn at line L7. By Theorem 1, n.gn.g is the cost of a path to a goal, so n.g≥C∗n.g \ge C^*. Since nn is at a goal, 0≤h(n.state)≤h∗(n.state)=00 \le h(n.\mathrm{state}) \le h^*(n.\mathrm{state}) = 0, so f(n)=n.gf(n) = n.g. Take any path π\pi from s0s_0 to a goal, with cost CC. In the iteration that pops nn, Lemma 4 gives a node qq in the frontier with f(q)≤Cf(q) \le C, and POP-MIN returned nn, so n.g=f(n)≤f(q)≤Cn.g = f(n) \le f(q) \le C. This holds for each such π\pi, so n.g≤C∗n.g \le C^*. Hence n.g=C∗n.g = C^*. □\square

With h=0h = 0, Theorem 5 is the optimality of uniform-cost search.

Theorem 6 (infinite spaces for f=g+hf = g + h). Let f=g+hf = g + h with hh admissible, let each state have finitely many successors, let each action cost be at least ϵ>0\epsilon > 0, and let some goal be reachable from s0s_0. Then the search stops and returns a path of cost C∗C^*.

Proof. Fix a path π\pi to a goal, with cost CC. By Lemma 4, until the search returns, the frontier is not empty, and POP-MIN returns a node with f≤Cf \le C. Each node mm has f(m)≥m.g≥ϵ⋅m.depthf(m) \ge m.g \ge \epsilon \cdot m.\mathrm{depth}, so each popped node has depth at most ⌊C/ϵ⌋\lfloor C/\epsilon \rfloor. With finite branching there are finitely many paths from s0s_0 of at most this depth, and by Lemma 2 each is pushed at most once. So only finitely many pops are possible, and the loop cannot end at line L13, because the frontier is not empty. So the search returns, and by Theorem 5 the cost is C∗C^*. □\square

Remark (other ff). Theorems 1 and 3 hold for every ff. Theorems 5 and 6 need f=g+hf = g + h with hh admissible. For f=hf = h, greedy best-first search, they fail. Let s0s_0 have two children: a state yy with h(y)=1h(y) = 1, whose child is a goal, and a state x1x_1 that starts an infinite chain x1→x2→⋯x_1 \to x_2 \to \cdots with no goal and h(xi)=1/(i+1)h(x_i) = 1/(i+1). All costs are 1. Each xix_i has f(xi)<1=f(y)f(x_i) < 1 = f(y), so the search pops x1,x2,…x_1, x_2, \ldots and never pops yy. It runs for ever, while a goal is reachable. ■\blacksquare

Back to Best-first search