One loop, many searches

Breadth-first, depth-first, Dijkstra and A* are usually taught as separate algorithms. They are one short loop with a single decision swapped out. Here you can swap it yourself and watch the search change.

The loop

Every search keeps a frontier of places it could go next and a record of places it has already visited. Each turn it asks one question: which frontier entry should I take out now? The highlighted line is where that question is answered, and it is the only place the famous algorithms differ.


      
p.removeChoice
Chooses which frontier entry to expand next, and returns it with the entries left over. This is the strategy.
p.isGoal
Says whether a state is the one we want.
p.nextActions
Lists the moves available from a state.
p.applyAction
Returns the state a move leads to. It must build a fresh state and never change the old one.
p.stepCost
Prices a single move.
p.heuristic
Guesses the remaining cost to the goal, for the strategies that use a guess.

The page runs the code you see here, not a lookalike. Two points are easy to miss. id(state) turns a state into a number, because two states with equal contents are different objects and === would never match them. And when a second route reaches a state already waiting in the frontier, only the cheaper route is kept.

Try it

Choose a strategy and press Play. Only the highlighted function in the right-hand panel changes. Drag the green and red markers, or paint walls and mud onto the map.

Strategy (removeChoice)
Expanded0
In frontier1
Route cost–
Route steps–
Frontier, in list order (next out is outlined)
Moves (nextActions)
Brush
Map

The parts that never change

Things to try

Same map, five strategies

Each tile is a complete run on the map above, using your current walls, mud and move rules. Visited cells are shaded from the first expanded (pale) to the last (strong). Compare how many cells each strategy had to touch with how good its route is.

What each swap does

StrategyTakes nextThe frontier acts likeGuarantee
Breadth-firstThe oldest entryA queueThe route with the fewest steps. Costs are ignored.
Depth-firstThe newest entryA stackNone. It finds a route if one exists, but not a good one.
Cheapest-firstLowest cost so farA priority queue on costThe cheapest route (Dijkstra's algorithm).
GreedyLowest estimate to goalA priority queue on the estimateNone. Fast on friendly maps and easily trapped.
A*Lowest cost so far plus estimateA priority queue on bothThe cheapest route, provided the estimate never overshoots.

The same idea carries well beyond maps. Sliding puzzles, route planners and action planners all supply their own isGoal, nextActions, applyAction and stepCost, then borrow a strategy from the table. The loop in the first section is the graph-search outline from Russell and Norvig, Artificial Intelligence: A Modern Approach.