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::p riority_queue 可能看起来是一个不错的选择,但事实并非如此。
-
自己实现 A* 是一个巨大的信心助推器,但在你完成之后,你应该尝试切换到使用 boost 提供的助推器。当我问这个问题时,我对安装它感到紧张,但安装非常简单,不会产生任何并发症;A* 并不是 boost 提供的唯一有用功能。(特别是,如果您不使用它们的字符串处理功能,您最终将编写自己的副本;我从个人经验出发...
你可以使用普通向量或数组来存储元素,然后使用std::make_heap
、std::push_heap
、std::pop_heap
、std::sort_heap
、std::is_heap
和std::is_heap_until
来管理它。
这允许您中断遏制并在优先级队列上实施自定义操作,而无需自己实现标准操作。
如果您仅限于 STL,则可以使用 STL Set 并不断擦除和重新插入元素(具有新的优先级)。
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),但对于大型集合可能需要更多时间。
STL priority_queue
不适合 A* 实现。您需要一个支持increase
操作的堆结构来更改已插入项目的优先级。使用 Boost.Heap 实现许多经典堆。
编辑:Boost.Graph库也有A *搜索的实现。
真的想使用 std::p riority_queue,这是我为此使用的解决方案:
当您需要更新已在优先级队列中的节点时,只需将具有相同状态的新节点以及新的成本值和父节点插入队列即可。此节点的最新更新副本将首先从队列中移除,并添加到您访问的集合中。要处理较旧的重复项,请在处理之前根据您访问的集合检查队列中的任何节点。如果它位于访问的集合中,则已经看到了通过此节点的最低成本路径,因此只需忽略它并处理下一个节点即可。
有三种可能的解决方案:
-
跟踪当前独立于优先级队列打开的节点列表。尝试以与关闭节点相同的方式创建节点列表。
-
创建节点映射(按坐标)到打开-关闭状态。
-
安装 Boost 库,其中包括 A* 的模板化实现(我认为在
<graph>
中)。
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 无法在 CLion 中构建 C++ 项目
- 运行同一解决方案的另一个项目的项目
- CMake-按正确顺序将项目与C运行时对象文件链接
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 欧拉项目#8答案是大以获得有效答案
- 从链接列表c++中删除一个项目
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 既然存在危险,为什么项目要使用-I include开关
- cmake在我的项目中所需的所有静态库都不成功
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- QT通过C++添加映射QML项目
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 按对象的特定方法按升序排列的C++优先级队列
- 使用2个键的cpp-stl::优先级队列排序不正确
- 在linux上调试巨大的C++项目
- 在其他文件中创建类时在 c++ 项目中不起作用
- 使外部项目可用于find_package CMake
- 根据条件和优先级搜索容器中的项目
- C++ A-star 实现 -- 确定节点是否已在打开项目的优先级队列中