TIGSource Forums

Developer => Technical => Topic started by: tiktokbob on April 01, 2012, 11:48:29 AM



Title: Some path finding help if I may? A* pathfinding
Post by: tiktokbob on April 01, 2012, 11:48:29 AM
So I have a simple path finding demo set up on a 2D grid using A*; I have one question and one interesting bug.  

The question ... in a strategy game when a unit is selected, typically the available range of movement is shown for the selected unit.  The idea of scanning every single map tile to see if it's within range and accessible to the unit seems pretty inefficient; granted you could limit it easily by distance but even then you're doing a lot of A* work.  If a unit has a movement range of 6 then that's 6 squares in every direction which is 168 squares (if I'm not mistaken?) to each run A* on.  Is there a better way?


The bug ... a picture is worth a thousand words ... I'm not entirely sure why A* has chosen a longer route here?  I've tried to reproduce this with different, but similar, layouts and I am not able to.  

(http://i.imgur.com/WtbyU.png?1)


Title: Re: Some path finding help if I may? A* pathfinding
Post by: PompiPompi on April 01, 2012, 12:04:44 PM
Err, yea A* is kind of a greedy algorithm, there are other faster versions of it like fast marching, sweaping and etc. Don't remember exactly.
You can make A * more efficient if you keep a map(2D array) in which the algorithm marks how many steps it took it to reach that cell. And if the A* reach the same cell from another direction, it can stop this search because it's already marked as visited with fewer steps.
You can also limit the A* algorithm to an allowed number of steps.
About the bug, that's what you have a debugger for, heh...


Title: Re: Some path finding help if I may? A* pathfinding
Post by: Rob Lach on April 01, 2012, 12:26:41 PM
just step through the alg's decisions with a debugger


Title: Re: Some path finding help if I may? A* pathfinding
Post by: tiktokbob on April 01, 2012, 12:46:08 PM
Err, yea A* is kind of a greedy algorithm, there are other faster versions of it like fast marching, sweaping and etc. Don't remember exactly.
You can make A * more efficient if you keep a map(2D array) in which the algorithm marks how many steps it took it to reach that cell. And if the A* reach the same cell from another direction, it can stop this search because it's already marked as visited with fewer steps.
You can also limit the A* algorithm to an allowed number of steps.

Thanks for the suggestions, I will have a look at fast marching, sweeping and play with some optimisation.  :)

About the bug, that's what you have a debugger for, heh...

For sure!  I just thought it might be something to do with A* rather than my implementation of it as I've read that at times A* does not always chose the best route and someone may have seen similar behaviour before.


Title: Re: Some path finding help if I may? A* pathfinding
Post by: PompiPompi on April 01, 2012, 01:59:08 PM
You probably don't need to optimize it that much, I just mentioned thre are faster algorithms.
But you can use the 2D Map to not make the fast marching algorithm have an insane complexity order. Because if you implement it the most straight forward way it will travel the same places many times, eventhough you already found a shroter path.


Title: Re: Some path finding help if I may? A* pathfinding
Post by: randomnine on April 01, 2012, 02:17:57 PM
A* will find the shortest route unless you implemented it incorrectly. You've got some bugfixing to do. Don't worry about optimisations until you've got it working - it should be finding the path you've indicated.

Quote
If a unit has a movement range of 6 then that's 6 squares in every direction which is 168 squares (if I'm not mistaken?) to each run A* on.  Is there a better way?

You don't have to run A* for each square. You just have to do something like A* once, flooding out to touch every square within six steps of the starting position. Use a flat heuristic (so the 'distance to the goal' is always assumed to be 0), ignore all nodes with costs greater than 6 and you'll hit every single node the unit can reach in a single pass.


Title: Re: Some path finding help if I may? A* pathfinding
Post by: tiktokbob on April 01, 2012, 11:58:16 PM
A* will find the shortest route unless you implemented it incorrectly. You've got some bugfixing to do. Don't worry about optimisations until you've got it working - it should be finding the path you've indicated.

Well as it happens, it's fixed, by fixing an apparently unrelated bug.  I am some what confused by the interaction between the two and at some point I'll take a closer look at what was happening.

You don't have to run A* for each square. You just have to do something like A* once, flooding out to touch every square within six steps of the starting position. Use a flat heuristic (so the 'distance to the goal' is always assumed to be 0), ignore all nodes with costs greater than 6 and you'll hit every single node the unit can reach in a single pass.

That makes a lot of sense, thank you!


Title: Re: Some path finding help if I may? A* pathfinding
Post by: tiktokbob on April 03, 2012, 05:55:32 AM
A* will find the shortest route unless you implemented it incorrectly. You've got some bugfixing to do. Don't worry about optimisations until you've got it working - it should be finding the path you've indicated.

In association with this:
Quote
Reading this description, you might guess that the heuristic is merely a rough estimate of the remaining distance between the current square and the target "as the crow flies." This isn't the case. We are actually trying to estimate the remaining distance along the path (which is usually farther). The closer our estimate is to the actual remaining distance, the faster the algorithm will be. If we overestimate this distance, however, it is not guaranteed to give us the shortest path. In such cases, we have what is called an "inadmissible heuristic."

Technically, in this example, the Manhattan method is inadmissible because it slightly overestimates the remaining distance. But we will use it anyway because it is a lot easier to understand for our purposes, and because it is only a slight overestimation. On the rare occasion when the resulting path is not the shortest possible, it will be nearly as short.

Taken from: http://www.policyalmanac.org/games/aStarTutorial.htm (http://www.policyalmanac.org/games/aStarTutorial.htm)

I realise this is an issue with using Manhattan distance than A*, but worth bearing in mind for corner case debugging where it's being used.



Title: Re: Some path finding help if I may? A* pathfinding
Post by: Dacke on April 04, 2012, 01:45:18 AM
Err, yea A* is kind of a greedy algorithm, there are other faster versions of it like fast marching, sweaping and etc. Don't remember exactly.

I just thought it would be good to put a little extra emphasis to what randomnine said.
A* is not a greedy algorithm. It is in fact guaranteed to give an optimal solution, as long as you use a heuristic that never-never-ever overestimates underestimatses the distance left to travel. The heuristic should only give the exact distance left or underestimate overestimate it.  (Which, as tiktokbob pointed out, is not true for the Manhattan distance. But this is really easy to fix.)

But it's actually even better than that! A* is guaranteed to give an optimal solution while at the same time looking through the lowest number of states possible (given a specific heuristic). So once you have decided to use a specific heuristic for estimating the distance left to travel, you can never-ever-possibly outperform A* (if you want to find the optimal solution)

edit: Fixed a horrible error where I mixed up overestimation and underestimation :-[


Title: Re: Some path finding help if I may? A* pathfinding
Post by: ham and brie on April 04, 2012, 03:28:30 AM
It is in fact guaranteed to give an optimal solution, as long as you use a heuristic that never-never-ever underestimates the distance left to travel. The heuristic should only give the exact distance left or overestimate it.

I think you've typed the opposite of what you meant. The heuristic should not overestimate the cost left.


Title: Re: Some path finding help if I may? A* pathfinding
Post by: ekun on April 04, 2012, 04:56:21 AM
It is in fact guaranteed to give an optimal solution, as long as you use a heuristic that never-never-ever underestimates the distance left to travel. The heuristic should only give the exact distance left or overestimate it.

I think you've typed the opposite of what you meant. The heuristic should not overestimate the cost left.

Indeed. A pathfinding heuristic function is admissible only if it doesn't overestimate the cost.

Common heuristics used are euclidean distance, and Manhattan distance (in the case where movement is restricted to the four grid aligned directions).


Title: Re: Some path finding help if I may? A* pathfinding
Post by: Dacke on April 04, 2012, 05:01:55 AM
Whoopsiedoopsie! :-[
Thank you for pointing out my error :gentleman:


Title: Re: Some path finding help if I may? A* pathfinding
Post by: PompiPompi on April 04, 2012, 09:01:59 AM
Hmm, I think you can do better than A* and still get the optimal solution.
There is this 4 directions sweaping algorithm... I don't recall.


Title: Re: Some path finding help if I may? A* pathfinding
Post by: Dacke on April 04, 2012, 10:34:53 AM
Given that the assumptions inherent to A* hold true for a specific problem, it is theoretically impossible to outpreform it when it comes to exploring as few nodes as possible (= as few squares as possible in a grid). A few years ago I could probably have recited the mathematical proof to you, but I forget :)

Quote from: Wikipedia
A* is also optimally efficient for any heuristic h, meaning that no algorithm employing the same heuristic will expand fewer nodes than A*, except when there are multiple partial solutions where h exactly predicts the cost of the optimal path. Even in this case, for each graph there exists some order of breaking ties in the priority queue such that A* examines the fewest possible nodes.

...

But if you have a problem where A*'s assumptions are false, you can do better. For example, A* only goes from point A to point B once. But if you are running a game where new enemies keep spawning all the time (and they all want to go to B), you may be better off with something like Dijkstra's algorithm (https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm). Dijkstra's algorithm can also be a superior choice for a racing game, where you can pre-compute the best route to the goal from every point on the track.


Title: Re: Some path finding help if I may? A* pathfinding
Post by: Dacke on April 04, 2012, 12:36:40 PM
Use a flat heuristic (so the 'distance to the goal' is always assumed to be 0)

That makes a lot of sense, thank you!

I just noticed this!
A* with heuristic=0 is another name for Dijkstra's algorithm :)


Title: Re: Some path finding help if I may? A* pathfinding
Post by: st33d on April 05, 2012, 03:17:18 AM
Hmm, I think you can do better than A* and still get the optimal solution.
There is this 4 directions sweaping algorithm... I don't recall.

I've spent several years studying it and optimising it. You can't do better than A* unless you've implemented it wrong.

There are graph optimisations like HSA* but it's still A*.

There are situations however where spreading out through all nodes may be quicker than performing A* for many agents trying to find one player, such as Lee and Aker's algorithm:

http://realtimecollisiondetection.net/blog/?p=83


Title: Re: Some path finding help if I may? A* pathfinding
Post by: rivon on April 05, 2012, 04:09:43 AM
You can do better... With quantum computers :)


Title: Re: Some path finding help if I may? A* pathfinding
Post by: Dacke on April 05, 2012, 06:01:47 AM
tsss.. :laughter:

For thread completion, here is the (fairly readable) 7 page original article with the mathematical optimality proof for A*.
http://www.cs.auckland.ac.nz/compsci709s2c/resources/Mike.d/astarNilsson.pdf

Quoting the last paragraph original article:
Quote
Thus we see that the formulation presented uses one function, h, to embody in a formal theory all knowledge available from the problem domain. The selection of h, therefore, permits one to choose a desirable compromise between admissibility, heuristic effectiveness, and computational efficiency.

In other words: you can do all sorts of crazy stuff with h to get pretty much any result you want.


Title: Re: Some path finding help if I may? A* pathfinding
Post by: st33d on April 06, 2012, 03:32:25 AM
Indeed, if you change the sign of H you get the best route away from the target.

Although the algorithm needs to be halted after a number of steps with the best pick so far to run in a game, because logically if the best node away from the target is unknown then the entire graph must be traversed.


Title: Re: Some path finding help if I may? A* pathfinding
Post by: Dacke on April 06, 2012, 04:19:41 AM
Ooh, I didn't know that. Sweet :D