Exercises 1 - Search
Practice for Lecture 1 and Lecture 2. These are not collected and not graded.
Throughout, assume graph search: a state is expanded at most once. These conventions decide most of the answers below and are very important to remember:
- When the search stops. Breadth-first and depth-first search terminate as soon as the goal is generated, so the goal never appears in their expansion order. Best-first search and A* terminate when the goal is expanded, so it does.
- Generation order. When a state is expanded, its children are generated in alphabetical order. Expanding generates , then .
- Expansion tie-break. When two states sitting on the frontier have the same priority, the one earlier in the alphabet is expanded first. This only ever comes up for best-first search and A*, because a plain queue and a plain stack have no priorities to tie in the first place. BFS and DFS get their order entirely from the generation rule above plus the discipline of the frontier.
- Depth-first ordering. A stack returns the most recent thing put on it, and children go on in generation order, so DFS expands the alphabetically last child first. Expanding generates and then , so is expanded next, not . (On the exam the tree is drawn and children are generated left to right, so this is the rightmost child. Alphabetical order plays that role here, because an edge list has no left and right.)
Problem 1: Uninformed Search
The state space graph below has initial state and goal state . Transition costs are on the edges and apply in both directions.
1.1. Trace breadth-first search on the graph above. List the states in the order they are expanded, then give the path the search returns and that path's cost.
Solution
Expansion order: . Path returned: , cost .
Expanding generates and . Expanding generates , , and . Expanding generates nothing new that matters. Expanding generates , and the search terminates there.
Note that was generated, back when was expanded, but never expanded itself, and is never expanded at all. Being on the frontier is not the same as having been expanded, and only the expanded states go in your answer.
BFS orders by number of transitions, not by cost, so it returns the first goal it can reach in three transitions. Whether is the cheapest way to reach a goal is a separate question, and one BFS never asks. Problem 1.3 asks it.
1.2. Now trace depth-first search on the same graph, listing the states in the order they are expanded and giving the path it returns with its cost.
Solution
Expansion order: . Path returned: , cost .
The stack drives down the alphabetically last branch each time. Expanding generates and , and comes off first. Expanding generates ; expanding generates and , so comes off first. Expanding generates and , so comes off. Expanding generates , and the search terminates.
Five transitions and cost , worse on both counts than what BFS found. DFS optimizes nothing at all: it returns whichever goal its stack stumbles into first, and here the stack walked most of the graph to find the long way around.
1.3. Trace best-first search, which orders its frontier by , by filling in the table below. Each column is one expansion, in order: the top row holds the state expanded and the bottom row holds its , the total cost of the path from to that state. The first column is done for you, and you may not need every column.
| Expansion | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| State | ||||||
| 0 |
Solution
| Expansion | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| State | ||||||
| 0 | 1 | 5 | 5 | 6 | 7 |
Path returned: , cost .
Watch expansions 3 and 4. and are both sitting on the frontier at , so the tie-break decides, and goes first because it is earlier in the alphabet. This is the only place on the page where that rule actually changes anything.
Note also that and get expanded even though neither is on the returned path. Best-first search has no way to know that, and problem 2.4 is about buying that knowledge with a heuristic.
1.4. BFS and best-first search returned different paths. Which one is optimal, and what exactly does the other one optimize instead?
Solution
Best-first search is optimal: costs , against for the BFS path. BFS optimizes the number of transitions rather than cost. Both paths here happen to use three transitions, but BFS commits to the first one it finds and never reconsiders, while best-first search keeps going until it is certain nothing cheaper remains. The two agree only when every transition costs the same.
Problem 2: Informed Search
Same graph, now with a heuristic written beside each state.
2.1. Trace A*, which orders its frontier by . Fill in the table below, one expansion per column as before, with the state expanded and its , , and at the moment of expansion.
| Expansion | 1 | 2 | 3 | 4 |
|---|---|---|---|---|
| State | ||||
| 0 | ||||
| 5 | ||||
| 5 |
Solution
| Expansion | 1 | 2 | 3 | 4 |
|---|---|---|---|---|
| State | ||||
| 0 | 1 | 5 | 7 | |
| 5 | 6 | 2 | 0 | |
| 5 | 7 | 7 | 7 |
Path returned: , cost .
Look at the very first choice. Ranked by alone, at beats at . Ranked by , sits at and at , so A* takes instead. Adding the one term reverses the decision. Problem 2.2 is about what that term is buying.
2.2. Suppose you dropped the term and ranked the frontier by alone. Would that search still be guaranteed to return the optimal path? Say what the term is doing for A*, and use this graph's first expansion to make the point concrete.
Solution
No. Ranking by alone throws away everything already spent to get where you are, so the search commits to whatever merely looks closest to the goal.
The first expansion shows it. From the frontier holds at and at , so ranking by takes , even though reaching costs where reaching costs . A* ranks the same two by : at against at , and takes .
That is what is for. It holds the search accountable for what a path has already cost, so a state that is cheap to reach but looks a little further from the goal can still win. Without it there is nothing to stop the search walking confidently in an expensive direction.
2.3. A* expanded four states; best-first search in problem 1.3 expanded six. Which two states did the heuristic save, and why were they skipped?
Solution
and . Best-first search expanded both because it ranks by alone, and at and they came up before the goal did at .
A* never touches them. Adding puts at and at , both well above the shared by every state on the optimal path. The heuristic is what tells A* that those two lead away from the goal, which is information best-first search simply does not have.
Problem 3: Heuristic Quality
Still the same graph, and still the heuristic from problem 2.
3.1. Fill in , the true future cost from to the goal, for every state; the first column is done for you. Then answer: is admissible?
| State | |||||||
|---|---|---|---|---|---|---|---|
| 5 | 7 | 2 | 6 | 5 | 3 | 0 | |
| 7 |
Solution
| State | |||||||
|---|---|---|---|---|---|---|---|
| 5 | 7 | 2 | 6 | 5 | 3 | 0 | |
| 7 | 9 | 2 | 6 | 6 | 3 | 0 |
Every , so is admissible. It is exact at , , and and an underestimate at , , and .
Two of these are worth checking carefully. by the direct edge , which happens to beat going back through and at . And , which is exactly the cost best-first search returned in 1.3, as it must be: at the initial state is the optimal solution cost.
3.2. Suppose a classmate proposes with and every other value the same as . Is admissible? Would A* with still have returned the optimal path on this graph?
Solution
is not admissible: , so it claims is further from the goal than it really is.
A* with would still return at cost . is not on the optimal path, and inflating it only makes A* avoid more eagerly than before.
That is the point worth taking away: inadmissibility means optimality is no longer guaranteed, not that it always breaks. You cannot test admissibility by running one example and liking the answer.
3.3. You have two admissible heuristics and for a different problem, given below, with neither better than the other everywhere. Fill in the row for the heuristic you should actually use, and say why.
| State | |||||
|---|---|---|---|---|---|
| 5 | 2 | 6 | 1 | 0 | |
| 3 | 4 | 6 | 3 | 0 | |
| use |
Solution
| State | |||||
|---|---|---|---|---|---|
| 5 | 2 | 6 | 1 | 0 | |
| 3 | 4 | 6 | 3 | 0 | |
| use | 5 | 4 | 6 | 3 | 0 |
Take at each state. Every value is still at most , since each one came from a heuristic that never overestimates, so the combination stays admissible, and it is at least as close to everywhere as either input. Closer to means fewer expansions (potentially)!
3.4. Suppose we run A* on a new problem and it generates nodes, not counting the root, finding the goal at depth . Estimate the effective branching factor .
Solution
Solve , so .
There is no closed form, so bracket it. gives , which undershoots; gives , which just overshoots. So .
A heuristic reporting on the same problem would be dramatically better: its search tree is nearly a single path to the goal.
Problem 4: Conceptual Miscellany
These do not depend on the graph above.
4.1. A classmate argues that best-first search does not need a priority queue:
We already keep a graveyard, so we never expand the same state twice. That is what stops us from wasting work. A plain FIFO queue would return the same path.
What is wrong with this argument?
Solution
The two structures do different jobs, and the graveyard cannot cover for the priority queue.
The graveyard prevents repeated work. Without it a search can expand the same state again and again, but it says nothing about which state to expand next.
The priority queue is what decides which state to expand next, and ordering by is what makes the first goal expanded the cheapest one. Swap in a FIFO queue and you no longer have best-first search, you have breadth-first search, which orders by number of transitions instead. Whenever transitions cost different amounts, that returns a different path, and usually a worse one. Problems 1.1 and 1.3 are exactly this case: BFS returned a path costing where best-first search returned one costing , and both searches kept a graveyard the whole time.
So the classmate has kept the mechanism that saves work and thrown away the mechanism that guarantees optimality on non-uniform cost problems.
That qualifier matters, because on a uniform cost problem the classmate would be right. When every transition costs the same, fewest transitions and cheapest are the same thing, so BFS is optimal and the priority queue buys nothing. The priority queue earns its keep exactly when costs differ.
4.2. For each situation, name the search strategy you would use and give a one-line reason.
- All transitions cost the same, and memory is tight.
- Transition costs vary and you have no idea how to estimate distance to the goal.
- Transition costs vary and you have an admissible, consistent heuristic.
- All transitions cost the same and you know the goal is exactly five transitions deep.
Solution
- Iterative deepening: it keeps only the current path in memory, like depth-first search, but because it tries every depth limit in increasing order it still returns the shallowest goal, which with uniform costs is the cheapest one. Plain depth-first search would fit the memory budget too, but it would return whichever goal it happened to reach first.
- Best-first search with : it is optimal for varying costs and needs no heuristic.
- A*: the heuristic cuts expansions, and admissibility plus consistency keeps it optimal under graph search.
- Depth-limited search with limit : it gets depth-first memory without the risk of diving past the goal, and there is no reason to pay for the repeated shallower passes iterative deepening would make when you already know the depth.
4.3. A* keeps both and for every state on the frontier, and its frontier is a priority queue rather than a plain queue or stack. Name two ways this makes A* more expensive than breadth-first search.
Solution
Bookkeeping per state. Every frontier entry stores , and has to be computed for it, where BFS stores nothing beyond the state and the path that reached it.
Cost per frontier operation. A priority queue costs per insertion and removal, where a plain queue or stack is .
Neither of these changes how many states get expanded, which is the thing A* is actually trying to reduce. So a heuristic is only worth using when the expansions it saves outweigh the overhead it adds on every state that remains.
Practice: admissibility and consistency
Each instance gives you a fresh state space graph, edge costs, and a heuristic. Fill in , decide both properties, and supply a witness where one fails. The checker accepts any genuine witness, not just the one it had in mind, and remember that the consistency inequality is directional.
Practice: search traces
Each instance draws a fresh search tree and asks for all five strategies at once, the way the exam does. Two conventions decide most of the answer, so read them each time: children are generated left to right, which means a stack expands the rightmost child first, and the strategies with a priority-queue frontier goal-test at expansion while the others goal-test at generation. Only the first group ever expands its own goal.
Practice: admissible combinations
Given two admissible heuristics, decide whether a combination of them is still admissible. The test that settles every row is the extreme case: if both inputs are exactly , can the expression come out above ?
Practice: completeness and optimality
For a strategy applied to a class of problem, decide whether completeness is guaranteed and whether optimality is. Both halves of each row matter: a strategy can be complete without being optimal, and the problem class is doing as much work in the question as the strategy is.