A real pet-peeve of mine is A* implementations that are based on grids.
For anyone who understands the origins and applications of the algorithm, these implementations offer crippled functionality and restrict the user to the problem domain of path finding.
A-Star is a
state based search algorithm. A state could describe anything from a state in a 15-puzzle problem to the current state of play in a game of chess -
it is not restricted to path finding!
Anyway, rant out of the way...
I implemented a more general A* solution a few years ago, but never posted it on the TGC boards. So here it is (click code button).
Whilst this code demonstrates the algorithm as applied to path finding, it is general enough to be applied to other search problems without much modification (you only need to change the node UDT definition and the heuristic function).
To run the demo, you need to download this graph file and place it in the same directory as the compiled executable.
[edit: url tag doesn't like files without extensions!]
http://www.ecs.soton.ac.uk/~dg503/demo
If you want to try your own graphs, I also produced a simple editor to create them with (I'll attach this in the next post). If I've lost you with all this talk of graphs, take a quick peek at the attached screenshot to refresh your memory.
This implementation supports directed graphs out of the box. In other words, you can specify that you can travel from a node A to another node B, but not from B to A. This might be useful for, as an example, a path that travels over a cliff (you can drop down from the cliff, but you can't travel back up it!). However, I didn't include the functionality to specify edge direction in the example editor, so you'll have to add it yourself. The editor stores connectivity data in a standard connectivity matrix, so this is easy to add.
Additionally, this example code is already set for nodes specified in 3D space (although again you'll have to update the editor yourself as I only made it for 2D graphs).
You can of course use this implementation in a grid-based world. It will even be more efficient as the neighbours of each 'grid cell' would be stored in a node's internal list, hence removing the need to check all eight neighbours for connectivity.
Please note that the code is not optimised. When I wrote these, the built-in DBPro array functions were a bit buggy, so I made a few quick functions to manage the priority queue and closed list. I leave this as an exercise to the reader to optimise these functions if needed (if you really want a super-fast priority queue, I recommend implementing it using a Splay tree).
Danny Gregory
BSc Computer Science - UG
University of Southampton