繁体   English   中英

C ++ A-star实现—确定一个节点是否已经在未清项目的优先级队列中

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

A *寻路算法的一个步骤要求在打开的节点列表中搜索您当前正在与之交互的节点,如果该节点尚不存在,则将该节点添加到列表中,或者更新该节点的值和父节点(如果存在)但是权重比当前版本的节点高。

STL priority_queue结构不支持这些行为。 我应该如何执行该步骤?

由于此问题引起了很多关注,因此进行了更新

  • std :: priority_queue看起来可能是个不错的选择,但事实并非如此。

  • 自己实现A *可以极大地增强信心,但是在完成之后,您应该尝试改用boost提供的方法。 当我问这个问题时,我对安装它感到不安,但是安装非常简单,不会产生任何麻烦。 A *不是boost提供的唯一有用的功能。 (特别是,如果您不使用它们的字符串处理功能,您最终将自己编写它的副本;我的经验是……)

STL priority_queue不适合A *实现。 您需要支持increase操作的堆结构,以更改已插入项目的优先级。 使用Boost.Heap实现许多经典堆的实现。

编辑: Boost.Graph库也具有A *搜索的实现

如果限于STL,则可以使用STL集并不断擦除和重新插入元素(具有新的优先级)。

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) );

时间复杂度仍为O(log N),但大型集合可能会花费更多时间。

如果您真的想使用std :: priority_queue,这是我用于此的解决方案:

当您需要更新优先级队列中已经存在的节点时,只需将状态相同,新的成本值和父节点的新节点插入队列中即可。 该节点的最新副本将首先从队列中移出,并添加到您的访问集中。 要处理较旧的重复项,请在处理之前对照访问的集合检查从队列中移出的任何节点。 如果它在访问集中,则已经看到了通过此节点的成本最低的路径,因此只需忽略它并处理下一个节点。

您可以使用简单的向量或数组来存储元素,然后使用std::make_heapstd::push_heapstd::pop_heapstd::sort_heapstd::is_heapstd::is_heap_until进行管理。

这使您可以打破包含并在优先级队列上实现自定义操作,而不必自己实现标准操作。

有三种可能的解决方案:

  1. 跟踪当前打开的节点列表,而与优先级队列无关。 尝试以与关闭节点相同的方式创建节点列表。

  2. 创建节点地图(按坐标)到开闭状态。

  3. 安装Boost库,其中包括A *的模板实现(我认为在<graph> )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM