A farmer must ferry a wolf, a goat and a cabbage across a river in a boat that holds the farmer and one other. Left alone together, the wolf eats the goat and the goat eats the cabbage.
(farmer, wolf, goat, cabbage) over {L, R}. That is 24 = 16 states. The boat is always where the farmer is, so it is not part of the state.(L, L, L, L) — everyone on the left bank.result(s, a) flips the farmer's bank, and the passenger's bank if there is one. The legality rule — no wolf alone with the goat, no goat alone with the cabbage — is a property of the resulting state, so we check it there and refuse the move.s == (R, R, R, R). One goal state.There is a duality here: you can define actions loosely and let some of them produce illegal states, or define them tightly so every state they reach is legal. Which did we just do, and what would the other choice look like?
Loosely. “Take the goat” is always an action when the goat is on your bank, and we reject the result if something gets eaten. The tight version would build the eating rule into the action set, so “cross alone” simply is not available when it would leave the wolf with the goat. Same graph, either way — but the loose version makes the illegal states visible, which is useful when you are learning, and the tight version never generates a child it has to throw away, which is useful when you are counting.
Root at the top. From every state that gets expanded, every available action is drawn as a child — that is the full tree, not just the route that works. Children come in three kinds. A new state gets a card and is expanded on the next row. An ✗ illegal state is a small red-edged leaf labelled with what gets eaten. A repeated state is the closed set refusing a move: most of those are just rowing back to where you came from, drawn as a dashed hook up to the parent; one is a move that reaches a state discovered by a different branch, drawn as a dashed edge across to it. Edge labels are the action: alone, or +W, +G, +C for who rides in the boat.
Take every greyed leaf above, and instead of stopping, expand it — and its children, and theirs. One dot per node. The state space never has more than two states at any depth; the unpruned tree more than doubles each row.
1, 1, 2, 4, 8, 18, 38, 86. The tree counts paths; the graph counts places. There are ten places.
| Depth | Graph search (closed set) | Tree search (no closed set) |
|---|---|---|
| 0 | 1 | 1 |
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 4 |
| 4 | 2 | 8 |
| 5 | 1 | 18 |
| 6 | 1 | 38 |
| 7 | 1 | 86 |
The state space has 10 states. Tree search has 86 nodes at depth 7 alone. Where did the other 76 come from, if there are only 10 places to be?
They are the same 10 states reached along different sequences of crossings — row the goat over, row back, row the goat over again, and you are at a state you have seen twice already, but the tree does not know that. The closed set is what turns the first column into the second, and in a space with cycles it is the difference between an algorithm that halts and one that does not.
Collapse every repeat in the tree onto the state it repeats and you get the graph on the left: ten states, ten crossings, one diamond. On the right, the six states the transition model refuses.
Every edge is on some optimal solution. The start and the goal each have exactly one.
Sixteen states minus these six. Note that RLLL and LRRR are doubly fatal.
Both solutions begin with take the goat and end with take the goat. Without tracing anything, why must that be so?
The goat is the only creature that is dangerous on both sides — it eats and gets eaten — so it is the only thing you can move first, and by the mirror-image argument the only thing you can move last. In the graph, the start has exactly one edge, and so does the goal.
take the goat → cross alone → take the wolf → take the goat → take the cabbage → cross alone → take the goattake the goat → cross alone → take the cabbage → take the goat → take the wolf → cross alone → take the goatTake the goat over, come back, take one of the other two over, bring the goat back, take the remaining one over, come back, take the goat. The two solutions differ only in whether the wolf or the cabbage goes on trip three, which is the diamond in the picture. The step people miss when solving it in their head is the fourth: a move that undoes progress, and that no greedy “get everything across” rule would ever choose. Breadth-first search finds it without noticing anything clever happened, which is the point.
Every crossing can be undone by crossing back, which is why the picture is symmetric and why bidirectional search would work here: grow from the goal as well as the start and they meet in the middle of the chain. It is also why every depth-first search on this problem, with the closed set, finds a solution of length 7 whatever order it tries things in — there is nowhere longer to go.