I would like to understand on a fundamental level the way in which A* pathfinding works. Any code or psuedo-code implementations as well as visualizations would be helpful.
feedback
|
It's far from the best, but this an implementation I did of A* in C++ a few years ago. It's probably better that I point you to resources than attempt to explain the entire algorithm. Also, as you read through the wiki article, play with the demo and see if you can visualize how it is working. Leave a comment if you have a specific question. | |||||||||||||||||||
feedback
|
DisclaimerThere are tons of code-examples and explanations of A* to be found online. This question has also received lots of great answers with a lot of useful links. In my answer I'll try to provide an illustrated example of the algorithm, which might be easier to understand than code or descriptions. Djikstra's algorithmTo understand A*, I suggest you first have a look at Djikstra's algorithm. Let me guide you through the steps Djikstra's algorithm will perform for a search. Our start-node is This is our starting point. We have a list nodes to examine, this list currently is:
We take the node with the lowest cost from our list of nodes (since our list only contains
and keep track of the previous node (shown as small pink letter below the node).
Again, we take the node with the lowest cost from our list (
The next node to examine is now
So as we did before, we examine the node with the lowest cost from our list, which is now
Next we examine A* algorithmSo you might wonder why I explained Djikstra to you instead of the A* algorithm? Well, the only difference is in how you weigh (or sort) your candidates. With Djikstra it's:
With A* it's:
Where Amit's page about heuristics has a good overview over common heuristics. | |||||||||||||
feedback
|
A* path finding is a best-first type search that uses an additional heuristic. The first thing you need to do is divide up your search area. For this explanation the map is a square grid of tiles, because most 2D games use a grid of tiles and because that's simple to visualize. Note however that the search area can be broken up in any way you want: a hex grid perhaps, or even arbitrary shapes like Risk. The various map positions are referred to as "nodes" and this algorithm will work any time you have a bunch of nodes to traverse and have defined connections between the nodes. Anyway, starting at a given starting tile:
For diagrams illustrating these steps, refer to this good beginner's tutorial. There are some improvements that can be made, mainly in improving the heuristic:
| |||||||
feedback
|
Amit's A* Pages were a good introduction for me. You can find a lot of good visualizations searching for AStar Algorithm on youtube. | |||
feedback
|
Here is a little article with an animated GIF that show's Dijkstra's Algorithm in motion. | |||
feedback
|
You might find ActiveTut's article on Path Finding useful. It goes over both A* and Dijkstra's Algorithm and the differences between them. It's geared toward Flash developers, but it should provide some good insight on the theory even if you don't use Flash. | |||
feedback
|
One thing that's important to visualize when dealing with A* and Dijkstra's Algorithm is that A* is directed; it tries to find the shortest path to a particular point by "guessing" which direction to look. Dijkstra's Algorithm finds the shortest path to /every/ point. | |||||||
feedback
|
So just as a first statement, A* is at heart a graph exploration algorithm. Usually in games we use either tiles or other world geometry as the graph, but you can use A* for other things. The two ur-algorithms for graph traversal are depth-first-search and breadth-first-search. In DFS you always fully explore down your current branch before looking at siblings of the current node, and in BFS you always look at siblings first and then children. A* tries to find a middle-ground between these where you explore down a branch (so more like DFS) when you are getting closer to the desired goal but sometimes stop and try a sibling if it might have better results down its branch. The actual math is that you keep a list of possible nodes to explore next where each has a "goodness" score indicating how close (in some kind of abstract sense) it is to the goal, lower scores being better (0 would mean you found the goal). You select which to use next by finding the minimum of the score plus the number of nodes away from the root (which is generally the current configuration, or current position in pathfinding). Each time you explore a node you add all its children to this list and then pick the new best one. | |||
feedback
|
On an abstract level, A* works like this:
| |||
feedback
|
I've been confused by a number of explanations of A* before I found this great tutorial: http://www.policyalmanac.org/games/aStarTutorial.htm I mostly referred to that when I wrote an implementation of A* in ActionScript: http://www.newarteest.com/flash/astar.html | ||||
feedback
|
Here is my favorite: http://www.raywenderlich.com/4946/introduction-to-a-pathfinding with implementation details for cocos2d framework in Objective-C language(for iPhone dev): http://www.raywenderlich.com/4970/how-to-implement-a-pathfinding-with-cocos2d-tutorial | |||
feedback
|