CS 440 · Lecture 2 · A worked formulation

Wolf, Goat, Cabbage

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.

A farmer, a wolf, a goat and a cabbage on a riverbank beside a small boat
Image: GeeksforGeeks

The formulation

Five things, and then the problem is a graph

State
Which bank each of the four is on: a 4-tuple (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.
Initial state
(L, L, L, L) — everyone on the left bank.
Actions
The farmer crosses alone, or with the wolf, with the goat, or with the cabbage — but only with something on his own bank. At most 4 actions in any state; the branching factor b is 4.
Transition model
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.
Goal test
s == (R, R, R, R). One goal state.
Action cost
Every crossing costs 1. So the cheapest solution is the one with the fewest crossings, and breadth-first search is optimal here. (Charge more for crossing with a squirming wolf and it would not be.)
Think

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?

The search tree

Breadth-first, top-down, every branch

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.

d=0d=1d=2d=3d=4d=5d=6d=7alone+W+G+Calone+W+Calone+Galone+Calone+Galone+Galone↶ +G↶ alone↶ +W↶ +G+W ↶ seen↶ +C↶ alone↶ +C+W ↶ seen↶ +GFWGCSTARTWGCF✗W eats GG eats CGCFW✗G eats CWCFGFWCGCFWGFCWG✗W eats GFGCWGCFW✗G eats CGFWCFGWCFWGCGOALWFGCFWGC✗G eats CFWGCWGFC✗W eats GWGFC✗W eats G
F farmerW wolfG goatC cabbageletters left of the dashed line are on the left bank

The same tree without a closed set

What the repeats would have grown into

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.

d=01d=11d=22d=34d=48d=518d=638d=786

1, 1, 2, 4, 8, 18, 38, 86. The tree counts paths; the graph counts places. There are ten places.

Nodes per depth, both ways.
DepthGraph search (closed set)Tree search (no closed set)
011
111
212
324
428
5118
6138
7186
Think

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?

The state space

The ten places, and the six you must never be in

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.

d=0d=1d=2d=3d=4d=5d=6d=7FWGCSTARTWCFGFWCGWFGCCFWGFWGCFGCWGFWCFGWCFWGCGOAL

Every edge is on some optimal solution. The start and the goal each have exactly one.

FWGC✗✗ goat eats cabbageFCWG✗✗ wolf eats goatFWGC✗✗ wolf eats goat and goat eats cabbageWGCF✗✗ wolf eats goat and goat eats cabbageWGFC✗✗ wolf eats goatGCFW✗✗ goat eats cabbage

Sixteen states minus these six. Note that RLLL and LRRR are doubly fatal.

Think

Both solutions begin with take the goat and end with take the goat. Without tracing anything, why must that be so?

The solutions

Two, both seven crossings

  1. take the goat → cross alone → take the wolf → take the goat → take the cabbage → cross alone → take the goat
  2. take the goat → cross alone → take the cabbage → take the goat → take the wolf → cross alone → take the goat

Take 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.

Reversible actions

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.