The A* algorithm is perhaps the most ubiquitous algorithm in games but also seemingly one of the more misunderstood algorithms. Not in the sense that people don’t know how to implement it (they do) but in failing to use it properly.

As you probably know, A* is a best-first graph-searching algorithm frequently used for finding a path from the start node to a goal node1. A* is typically cast as operating on an evaluation function

f(x) = g(x) + h(x)

where g(x) describes the true cost from the start node to the current node x, and h(x) is a heuristic function that estimates the cost in moving from x to the nearest goal node (nearest, according to the metric).

When h(x) is admissible, meaning it doesn’t overestimate the true cost of reaching a goal, A* is guaranteed to find a shortest path (if one exists). And herein lies the problem: much too much effort is spent in games in finding the shortest paths! There is a near obsession with admissible heuristics, which is completely misguided! Who the heck cares about the shortest path?! In our everyday lives we rarely, if ever, take a shortest path. Instead, we often optimize for search effort, taking a path we’re familiar with (which we’ve chunked or otherwise memorized so as to require no search). Well, the same applies to games and the A* algorithm. We can reduce search effort, sometimes drastically, by forfeiting the guarantee of an optimal shortest-path using nonadmissible heuristics.

Though they are (often) ignored in games, the power of nonadmissible heuristic functions is nothing new, of course. Going back to the original paper [Hart68] and the section entitled “The Heuristic Power of the Estimate h-hat” we find the authors pointing out the value of non-admissible heuristics, stating

The algorithm would no longer be admissible, but it might be more

desirable, from a heuristic point of view, than any admissible algorithm.

We can find this echoed in many places, including in Barr & Feigenbaum’s Handbook of AI [Barr82, pg. 65, in regards to A*]

Second, it may be less important to find a solution whose cost is absolutely minimum than to find a solution of reasonable cost within a search of moderate length. In such a case, one might prefer an h* that evaluates nodes more accurately in most cases but sometimes overestimates the distance to a goal, thus yielding an inadmissible algorithm.

and a paper by Dechter and Pearl [Dechter85]:

It has been found, however, that maintaining the admissibility of A* is too restrictive; it limits the selection of heuristics to those that only underestimate costs, and it forces A* to spend a disproportionately long time discriminating among roughly equal candidates. As a result, several attempts have been made to execute A* with nonadmissible estimates while simultaneously limiting the degree of suboptimality [5, 17, 18, 20] and minimizing the computational difficulties that overestimates may induce [1].

I wish AI programmers all over the world would think more about the heuristic function, if they haven’t already, and stop being totally obsessed with shortest paths. Instead, use nonadmissible heuristics and cut your search effort in half2!

BTW, the A* algorithm turns 40 years this year, and it’s hard to say things that haven’t already been said about the algorithm. That said, in a recent livejournal post, David Eppstein (a UCI professor and computational geometer) talks about the A* algorithm in a fresh perspective. David likens A* to a preconditioner that adjusts the weights of a graph to allow another algorithm (notably, but not necessarily, Dijkstra) to work more efficiently. Though David too makes the mistake of thinking that (or, at least, presenting it as if) A* is for shortest paths only. It’s not, dammit. Still worth reading!

Footnotes

The observant will note that I said “a goal” instead of “the goal.” It is not always clearly stated that A* is capable of searching for multiple goals at once (in the sense that reaching any of the goals is our, uh, goal), but it is. Factor of two is not a promise.

References