C++ A-star implementation — determining whether a node is already in the priority queue of open items

我的未来我决定 提交于 2020-01-02 14:05:52

问题


One step in the A* pathfinding algorithm requires searching the list of open nodes for the node you're currently interacting with, and adding that node to the list if it isn't already there, or updating its value and parent, if it's present but with a higher weight than the current version of the node.

These behaviors aren't supported in the STL priority_queue structure. How should I implement that step?

Updates since this question is getting a lot of views:

  • std::priority_queue may look like a good choice for this, but it isn't.

  • Implementing A* yourself is an enormous confidence-booster, but after you've done it, you should try to switch to using the one provided by boost. I was nervous about installing it when I asked this question, but installation is very easy and won't produce any complications; and A* isn't the only useful functionality that boost provides. (In particular, if you don't use their string-processing functionality, you'll end up writing your own copy of it; I speak from personal experience...)


回答1:


You can use a plain vector or array to store the elements and then use std::make_heap, std::push_heap, std::pop_heap, std::sort_heap, std::is_heap and std::is_heap_until to manage it.

This allows you to break containment and implement custom operations on a priority queue, without having to implement the standard operations yourself.




回答2:


If you are limited to STL you could use STL Set and constantly erasing and re-inserting the elements (with new priority).

Set< pair<int,int> > s; // < priority,value >
s.insert( make_pair(0,5) );

// Decrease Key operation //
s.erase( s.find( make_pair(0,5) ) );
s.insert( make_pair(1,5) );

Time complexity is still O(log N) but it will probably take more time for large sets.




回答3:


STL priority_queue does not suit for A* implementation. You need a heap structure that supports the increase operation to change the priority of already inserted items. Use Boost.Heap for an implementation of many classical heaps.

EDIT: Boost.Graph library has an implementation of A* search too.




回答4:


Here is the solution I used for this if you really want to use std::priority_queue:

When you need to update a node that is already in the priority queue, just insert a new node having the same state and a new cost value and parent into the queue. The most recently updated copy of this node will come off the queue first and be added to your visited set. To deal with the older duplicates, check any node coming off the queue against your visited set before processing it. If it is in the visited set then the lowest-cost path through this node has already been seen, so just ignore it and process the next node.




回答5:


There are three likely solutions to this:

  1. Track the list of nodes currently open independently of the priority queue. Try creating a list of nodes in the same manner you do for closed nodes.

  2. Create a map of nodes (by coordinate) to open-closed state.

  3. Install the Boost library, which includes a templated implementation of A* (I think in <graph>).



来源:https://stackoverflow.com/questions/11912736/c-a-star-implementation-determining-whether-a-node-is-already-in-the-priori

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!