9

I'm in the process of developing a simple 2d grid based sim game, and have fully functional path finding.

I used the answer found in my previous question as my basis for implementing A* path finding. (Pathfinding 2D Java game?).

To show you really what I'm asking, I need to show you this video screen capture that I made. I was just testing to see how the person would move to a location and back again, and this was the result...

http://www.screenjelly.com/watch/Bd7d7pObyFo

Different choice of path depending on the direction, an unexpected result. Any ideas?

Community
  • 1
  • 1
Relequestual
  • 11,631
  • 6
  • 47
  • 83
  • 1
    Agreed, the video is an excellent idea. – Mike Burton Jul 25 '09 at 17:09
  • Yeh, Screenjelly is awesome for things like this! – Relequestual Jul 25 '09 at 17:25
  • To anyone wondering, screenjelly allows you to record directly from your browser using a java web applet! and then links in with your twitter account for ID. Clever! – Relequestual Jul 25 '09 at 17:36
  • You've almost certainly read my answer and won't read it again, so I'll paste my most recent edit here because I think it's likely to be the simplest way to help yourself understand the behaviour you're seeing: If you're really interested in learning what's going on, I'd suggest rendering the steps of the A* search. Given your question, it might be very eye-opening for you. – Mike Burton Jul 25 '09 at 18:04
  • A floodfill path-finding algorithm would be even faster than A* in this case. It would only need O(k*n). – Georg Schölly Jul 25 '09 at 18:33
  • Re mike, ill comment in your answer. Re gs, it may well do, but I only just about understand how A* works, and I used an already working example which contained a very basic API type interface. I'll stick to A* for now, as CPU usage isn't an issue. If eventually I find it taking up too much, I'll be sure to look into it. thanks – Relequestual Jul 25 '09 at 19:17
  • possible duplicate of [How do I find the most “Naturally" direct route using A-star (A*)](http://stackoverflow.com/questions/845626/how-do-i-find-the-most-naturally-direct-route-using-a-star-a) – BlueRaja - Danny Pflughoeft Jul 17 '12 at 18:12
  • The link is either spam or broken. – flup Feb 22 '14 at 21:37

9 Answers9

3

If you're looking for a simple-ish solution, may I suggest a bit of randomization?

What I mean is this: in the cokeandcode code example, there is the nested-for-loops that generate the "successor states" (to use the AI term). I refer to the point where it loops over the 3x3 square around the "current" state, adding new locations on the pile to consider.

A relatively simple fix would (should :)) be isolate that code a bit, and have it, say, generated a linkedlist of nodes before the rest of the processing step. Then Containers.Shuffle (or is it Generics.Shuffle?) that linked list, and continue the processing there. Basically, have a routine say, "createNaiveNeighbors(node)" that returns a LinkedList = {(node.x-1,node.y), (node.x, node.y-1)... } (please pardon the pidgin Java, I'm trying (and always failing) to be brief.

Once you build the linked list, however, you should just be able to do a "for (Node n : myNewLinkedList)" instead of the

for (int x=-1;x<2;x++) {

    for (int y=-1;y<2;y++) {

And still use the exact same body code!

What this would do, ideally, is sort of "shake up" the order of nodes considered, and create paths closer to the diagonal, but without having to change the heuristic. The paths will still be the most efficient, but usually closer to the diagonal.

The downside is, of course, if you go from A to B multiple times, a different path may be taken. If that is unnacceptable, you may need to consider a more drastic modification.

Hope this helps! -Agor

agorenst
  • 2,425
  • 14
  • 18
  • wow, thanks Agor. Although this may not be chosen as "The Answer" for my exact question, it IS the answer to my WalkLikeHumanHeuristic comment, which i made before I saw this. I can't say I understand everything you said, but I get the general idea of it. I shall definatly look into this. If you would like to join my team on this game (Team including me...) and implement this, I'd be happy to give it a go! – Relequestual Jul 25 '09 at 19:41
  • No problem, happy to help. I'm flattered about the invitation, but I'm still a student (and working over the summer), so I must decline. Good luck, though! – agorenst Jul 25 '09 at 20:23
  • I am also a student :) although not doing a masters unlike yourself. Ok sure, no rush. I'm still looking for a job! – Relequestual Jul 25 '09 at 20:27
  • Something else to consider is weighting. It could be as simple as working out the best route in terms of cost: walking on the grass costs 2 whereas walking on the path costs 1, which encourages walking over certain types of terrain, or it could be used in another way to say changing direction costs 1 and moving costs 1, to encourage movement in straight lines. Instead of counting the total number of moves you count the total 'cost' (which is the same thing until you introduce different 'costs') – NibblyPig Apr 06 '10 at 14:54
2

Both of the paths are of the same length, so the algorithm is doing its job just fine - it's finding a shortest path. However the A* algorithm doesn't specify WHICH shortest path it will take. Implementations normally take the "first" shortest path. Without seeing yours, it's impossible to know exactly why, but if you want the same results each time you're going to have to add priority rules of some sort (so that you're desired path comes up first in the search).

oggy
  • 3,483
  • 1
  • 20
  • 24
  • If you look at the first link, and follow the answer to that question, the page actually contains links to all the pathfinding code I used. Under investigation, I have the choice of 4 heuristics. A* heuristic (based on cost only), Closest, ClosestSquared and Manhattan. I shall try the other 3, as A* is the default. – Relequestual Jul 25 '09 at 17:23
  • What's this A* heuristic of which you speak? A* uses currentCost + estimate_of_remainder ("hueristic"). Closest, ClosestSquared, Manhattan are the heuristics, but I know of none named "A* heuristic". – Michael Deardeuff Jul 25 '09 at 17:56
  • My mistake. It is only an interface class! Still learning alot! :) It was on the ClosestHeuristic. Tried out the other 2. The ClosestSquaredHeuristic went a bit funny sometimes, while the ManhattanHeuristic avoided zig-zagging, which looks better. I wonder if theres a WalkLikeHumanHeuristic... – Relequestual Jul 25 '09 at 19:26
  • Humans don't tend to have to go from one grid square to another! – Kylotan Jul 28 '09 at 11:11
  • Yeh, I know, but I mean within a 2d grid based environment. Guess randomization is closest I can get. – Relequestual Jul 28 '09 at 19:23
2

The reason is the path you want the algorithm to go.
I don't know the heuristic your A* uses but in the first case it has to go to the end of the tunnel first and then plans the way from the end of the tunnel to the target.

In the second case the simplest moves to the targets are going down till it hits the wall and then it plans the way from the wall to the target.

Most A* I know work with a line of sight heuristic or a Manhattan Distance in the case of a block world. This heuristics give you the shortest way but in case of obstacles that force to go a way that is different from the line of sight the ways depend on your starting point.
The algorithm will go the line of sight as long as possible.

Janusz
  • 187,060
  • 113
  • 301
  • 369
2

The reason why is actually pretty simple: the path will always try to have the lowest heuristic possible because it searches in a greedy manner. Going closer to the goal is an optimal path.

If you allowed diagonal movement, this wouldn't happen.

rlbond
  • 65,341
  • 56
  • 178
  • 228
  • You know, that would make sense. I don't plan to allow diagonal movement as this raises issues with corners of rooms. This IS only the 2nd game ive made in java, the first being a poor rendition of the classic helicopter game... so yeh, learn as I go, try to keep it fairly simple. I expect I'll open it up and allow other developers to chip in once I have something good established. – Relequestual Jul 25 '09 at 17:27
1

The most likely answer is that going straight south gets it closest to its goal first; going the opposite way, this is not a choice, so it optimizes the sub-path piecewise with the result that alternating up/across moves are seen as best.

If you want it to go along the diagonal going back, you are going to have to identify some points of interest along the path (for example the mouth of the tunnel) and take those into account in your heuristic. Alternatively, you could take them into account in your algorithm by re-computing any sub-path that passes through a point of interest.

Back in the day they used to do a pre-compiled static analysis of maps and placed pathfinding markers at chokepoints. Depending on what your final target is, that might be a good idea here as well.

If you're really interested in learning what's going on, I'd suggest rendering the steps of the A* search. Given your question, it might be very eye-opening for you.

Mike Burton
  • 3,010
  • 24
  • 33
  • Thanks Mike, I really love Stack, and value the people who post answers, so I would have re read when I saw the edited note. Thank you :) I'm not sure I completely understand what you mean, but I think I see what your saying. As it's a sim game, and eventually anything can change, I don't think I can use markers. I only JUST understand how it works, and remember a website which shows the progress of A*, which I will look at. I could implement it into my game, although I think it may be a bit too much for me at my level. I changed the heuristic to the manhattan, and it went straight both times. – Relequestual Jul 25 '09 at 19:23
1

In each case it's preferring the path that takes it closer to its goal node sooner, which is what A* is designed for.

chaos
  • 122,029
  • 33
  • 303
  • 309
0

If I saw right, the sphere is moving first to the right in a straigt line, because it cannot got directly toward the goal (path is blocked). Then, it goes in a straight line toward the goal. It only looks diagonal.

Burkhard
  • 14,596
  • 22
  • 87
  • 108
0

Does your search look in the 'down' direction first? This might explain the algorithm. Try changing it to look 'up' first and I bet you would see the opposite behavior.

Ben Childs
  • 4,480
  • 1
  • 21
  • 9
0

Depending on the implementation of your astar you will see different results with the same heuristic, as many people have mentioned. This is because of ties, when two or more paths tie the way you order your open set will determine the way the final path will look. You will always get the optimal path if you have an admissible heuristic, but the nodes visited will increase with the number of ties you have(relative to a heuristic producing not as many ties).

If you dont think visiting more nodes is a problem i would suggest using the randomization (which is your current accepted answer) suggestion. If you think searching more nodes is a problem and want to optimize i would suggest using some sort of tiebreaker. It seems you are using manhattan distance, if you use euclidian distance when two nodes tie as a tiebreaker you will get more straight paths to the goal and you will visit fewer nodes. This is ofcourse given no traps or block of line of sight to the goal.

To avoid visiting nodes with blocking elements in the line of sight path i would suggest finding a heuristic which takes into account these blocking elements. Ofcourse a new heuristic shouldnt do more work than a normal A star search would do.

I would suggest looking at my question as it might produce some ideas and solutions to this problem.

Community
  • 1
  • 1
Tore
  • 579
  • 1
  • 6
  • 19