【问题标题】:Which data structure is more efficient for A*?哪种数据结构对 A* 更有效?
【发布时间】:2022-01-14 10:53:09
【问题描述】:

在 A* 搜索中,哪种数据结构更高效?最小堆或二叉搜索树。

考虑到要经常处理以下操作: (a) 提取分钟 (b) 搜索节点 (c) 更新节点 (d) 插入一个节点

注意:搜索操作会非常频繁,因为我们需要检查 A* 的打开列表中每个可能的子节点是否存在。

【问题讨论】:

  • 这可能需要更长的时间,但您始终可以同时实现这两种方法,并为它们计时,看看哪一种更适合您
  • 在 A* 算法中您究竟需要 search 什么?如果您指的是更新节点的分数,那么您已经拥有该节点(来自正在搜索的树),并且可以确保您拥有(并保持)与相关堆节点的连接。我不明白为什么你真的需要在堆中搜索某个键。

标签: python-3.x data-structures binary-search-tree a-star min-heap


【解决方案1】:

最小堆是一种比平衡二叉搜索树简单得多的数据结构,它通常在数组中实现,这样可以减少内存使用并提高缓存局部性。

由于这些原因,如果你做得对,最小堆实现会快得多。

不过,在基于数组的最小堆中实现减少键操作通常很棘手。通常的解决方案是根本不实现reduce-key,而只是在与节点的距离减小时在最小堆中插入另一条记录。

这不会增加算法的时间复杂度,最小堆将占用 O(|E|) 空间。如果你的图非常密集,那么一个节点的权重可能会减少很多次,这种内存消耗可能太多了。如果是这样,那么只要堆中超过一半的条目无效,您就应该清理最小堆 - 删除无效条目并重新堆放。这将使内存消耗降低到 O(|V|),而不会显着影响运行时间。

【讨论】:

  • @aks, a),不,您只需将当前距离保留在单独的数组中的每个顶点。当距离减小时,你将一个节点放入堆中,然后你就可以识别出无效的堆节点,因为它们的距离不匹配。
  • @aks, b) 不,这意味着删除无效的堆节点,正如我之前的评论中提到的,您可以在恒定时间内识别出来。清理过程应该只需要对堆数组进行一次扫描,然后重新堆化,这两个过程都需要 O(|V|) 时间。请注意,堆中不会有有效的关闭节点,因此您无需查看关闭列表。
  • 通常顶点是密集编号的,所以数组(python中的列表)比字典存储顶点信息要好。
  • 你一直说当不需要线性搜索时你必须进行线性搜索:)
  • 2D numpy 数组是个不错的选择
猜你喜欢
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 1970-01-01
  • 2021-03-30
  • 2012-01-09
  • 1970-01-01
相关资源
最近更新 更多