Advertisement

Help fix my A* Design

Started by October 16, 2006 10:00 PM
11 comments, last by Timkin 18 years, 1 month ago
Quote: Original post by NotAYakk
Kylotan, adding to the middle of a vector or deque is an O(n) operation. Horridly expensive.

The STL uses a heap to implement it's priority queue -- O(lg n) sorted insert.

Wouldn't it be a good idea to at least get the A* algorithm working using a priority queue, and then speed up the "get next" and "add" abstractions?


The point I was making is that big-O notation is only a guide and is not the only consideration in algorithm performance. Sometimes the less intuitive approach works better because it is simpler and makes better use of the hardware.

Bear in mind that multiple consecutive vector or deque insertions can potentially be as efficient as a single one, if what you're inserting is contiguous. This is actually quite common in A* when you come to add several sibling nodes. Or add them to the end and perform a linear search - this is typically nowhere near as bad as you may expect if your node structure is compact and your comparison criteria is simple.

I know how the STL (typically) implements its priority queue - it implements it in a way that is fairly good if you don't ever want to traverse that structure (which you almost always do) and don't want to remove elements from the structure (which you usually do).

You perhaps also forget that while finding the best element is constant time, actually popping it is done in logarithmic time. Using std::priority_queue does not allow any practical optimisation of that operation.

I tend to start off with quite naive implementations and then tune them up as I go; unfortunately the priority queue adapter limits your options somewhat.
Yeah I see what you mean now... I have implemented my algorithm except for the very last part:
// If two or more paths reach a common node, delete all those paths
// except the one that reaches the common node with the minimum cost

Since I'm using a priority_queue I can't access any path but the top one. I tried not implementing this last step but the number of paths in the queue becomes huge in grids where most of the terrain is walkable.

Thanks for your advice :)
Advertisement
Quote: Original post by sled
Yeah I see what you mean now... I have implemented my algorithm except for the very last part:
// If two or more paths reach a common node, delete all those paths
// except the one that reaches the common node with the minimum cost

Since I'm using a priority_queue I can't access any path but the top one. I tried not implementing this last step but the number of paths in the queue becomes huge in grids where most of the terrain is walkable.

Thanks for your advice :)


Dealing with 'collisions' in the search process (where you find a state you've previously considered) requires a reverse lookup of the (cost,node) mapping. At worst this is an O(n) operation every time you make a new node. Clever bookkeeping can reduce this cost, but at the cost of storing more information.

This topic is closed to new replies.

Advertisement