function aStar(grid: Grid, start: Cell, goal: Cell) {const open = new MinHeap<Cell>([start]);
const distance = new Map([[start, 0]]), parent = new Map();
while (open.size > 0) {const current = open.pop(); // lowest score = distance + heuristic
if (current === goal) return rebuild(parent, current);
for (const neighbor of neighbors(grid, current)) {const newDistance = distance.get(current)! + 1;
if (newDistance < (distance.get(neighbor) ?? Infinity)) {distance.set(neighbor, newDistance); parent.set(neighbor, current);
open.push(neighbor, newDistance + heuristic(neighbor, goal));
}
}
}
}
Start at (12, 1), goal at (5, 42). The open set holds only the start.
Understanding A*
The idea
A* keeps an open set of cells to explore and always expands the one with the lowest f = g + h, where g is the cost from the start so far and h is an estimate of the cost still to go. With h = 0 it is Dijkstra; with a good h it heads straight for the goal and expands far fewer cells.
On a grid with 4-way movement the Manhattan distance is the natural heuristic. It never overestimates, so A* is guaranteed to return a shortest path; the closed cells you see are the price of that guarantee.
The four stages
Complexity
Versus its siblings
Pseudocode
A*(start, goal)
open ← {start}; dist[start] ← 0while open not empty
current ← node in open with lowest dist + heuristic
if current = goal: return path via parent
for each neighbour of current
if dist[current] + 1 < dist[neighbour]
dist[neighbour] ← dist[current] + 1; parent[neighbour] ← current; add neighbour to open
When to use
Pitfalls
History
Peter Hart, Nils Nilsson and Bertram Raphael published A* in 1968 at Stanford Research Institute, for Shakey, the first mobile robot that could reason about its actions. It generalised Dijkstra’s 1959 algorithm by adding the heuristic term.