A*,开放列表的最佳数据结构是什么?

2023-12-24

免责声明:我真的相信这不是类似问题的重复。我读过这些内容,他们(大多数)建议使用堆或优先级队列。我的问题更多的是“我不明白这些在这种情况下如何运作”。

简而言之:

我指的是典型的 A*(A-star)寻路算法,如维基百科上所述(例如):

https://en.wikipedia.org/wiki/A*_search_algorithm https://en.wikipedia.org/wiki/A*_search_algorithm

更具体地说,我想知道使用什么是最好的数据结构(可以是单个众所周知的数据结构,或它们的组合),这样您就不会在算法的任何操作上获得 O(n) 性能要求在开放清单上做。

据我了解(主要来自维基百科文章),需要对打开列表进行的操作如下:

此列表中的元素必须是具有以下属性的 Node 实例:

  • 位置(或坐标)。为了便于讨论,假设这是一个值范围为 0 到 64516 的正整数(我将 A* 区域大小限制为 254x254,这意味着任何坐标集都可以在 16 位上进行位编码)
  • F 分数。这是正浮点值。

鉴于这些,操作是:

  • 将节点添加到打开列表中:如果存在具有相同位置(坐标)的节点(但可能具有不同的 F 分数),则替换它。
  • 从打开列表中检索(并删除)F 分数最低的节点
  • (检查是否存在并)从列表中检索给定位置(坐标)的节点

据我所知,使用堆或优先级队列作为打开列表的问题是:

  • 这些数据结构将使用F-score作为排序标准
  • 因此,向这种数据结构添加节点是有问题的:如何最佳地检查具有相似坐标集(但 F 分数不同)的节点是否已存在。此外,即使您能够以某种方式进行此检查,如果您确实找到了这样的节点,但它不在堆/队列的顶部,如何以最佳方式删除它以使堆/队列保持其正确的顺序
  • 此外,检查是否存在并根据位置删除节点并不是最佳的,甚至是不可能的:如果我们使用优先级队列,我们​​必须检查其中的每个节点,如果找到则删除相应的节点。对于堆来说,如果需要这样的删除,我想所有剩余的元素都需要被提取并重新插入,以便堆仍然是堆。
  • 这种数据结构唯一有效的剩余操作是当我们想要删除 F 分数最低的节点时。在这种情况下,运算时间复杂度为 O(Log(n))。

此外,如果我们创建一个自定义数据结构,例如使用哈希表(以位置为键)和优先级队列的数据结构,我们仍然会有一些操作需要对其中任何一个进行次优处理:为了使它们保持同步(两者都应该具有相同的节点),对于给定的操作,该操作在其中一种数据结构上总是次优的:按位置添加或删除节点在哈希表上会很快,但在优先级队列上会很慢。删除 F 分数最低的节点在优先级队列上会很快,但在哈希表上会很慢。

我所做的是为使用其位置作为键的节点创建一个自定义哈希表,该哈希表还跟踪具有最低 F 分数的当前节点。添加新节点时,它会检查其 F 分数是否低于当前存储的最低 F 分数节点,如果是,则替换它。当您想要删除一个节点(无论是按位置还是按 F 得分最低的节点)时,此数据结构就会出现问题。在这种情况下,为了更新保存当前最低 F 分数节点的字段,我需要迭代所有剩余节点,以找到现在哪一个具有最低 F 分数。

所以我的问题是:有没有更好的方法来存储这些?


您可以将哈希表和堆结合起来,而不会出现缓慢的操作。

将哈希表映射位置到堆中的索引而不是节点。

对堆的任何更新都可以将自身(这需要堆了解哈希表,因此这是侵入性的,而不仅仅是两个现成实现的包装器)同步到哈希表,并具有尽可能多的更新(每个 O( 1),显然)作为堆中移动的项目数,当然只是log n项目可以因插入、删除最小或更新键而移动。哈希表找到节点(在堆中)来更新 A* 的父更新/G 更改步骤的键,因此速度也很快。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

A*,开放列表的最佳数据结构是什么? 的相关文章

  • 3Leetcode求和算法

    我在使用 3sum 算法的以下输入时遇到问题 我是 得到 超过时间限制 我的算法对于这个输入来说太慢了吗 有什么建议如何改进吗 leetcode原题 给定一个由 n 个整数组成的数组 nums nums 中是否存在元素 a b c 使得 a
  • C++ 中的 Java HashSet 等效项

    我很好奇 C 中是否有类似于 Java HashSet 的东西 IE 一个快速查看的数据结构 因为我只会运行 contains e 在上面 同样 如果你能启发我如何做 contains 无论您提出什么数据结构 我都会非常感激 O 请不要发帖
  • set()是如何实现的?

    我见过有人这么说setpython 中的对象具有 O 1 成员资格检查 他们如何在内部实施以实现这一点 它使用什么类型的数据结构 该实施还有哪些其他影响 这里的每个答案都非常有启发性 但我只能接受一个 所以我将选择最接近我原来问题的答案 谢
  • 将自行车分配给人员 - 第一优先级(距离最近的人最近的自行车)

    将网格传递给某个位置有自行车和人员的函数 c A a b D d B C Output 像这样的东西 A 1 B 3 C 8 D 1 其中 A 是人 1 是到达自行车所需的步数 标准 距离自行车最近的人 优先获得自行车 单辆自行车不能分配给
  • 何时使用 Box> 或 Vec>?

    什么时候设计一个嵌套的数据结构才有意义 Box and a Vec 或相反亦然 似乎在大多数情况下 您想在堆上存储多个固定大小的东西 Box是多余的 因为它唯一的 作用是堆分配一个 单个值 以及一个正常的Vec已经在堆上分配其存储空间 背景
  • 如何在javascript中实现deque数据结构?

    我正在用 javascript 学习数据结构 我现在的重点是如何实现双端队列 编辑 从下面的评论中我得到了有关如何实施的有用指示deque based array 有没有一个具体实施的方向deque based object使用类 我明白了
  • PHP 中的 MPTT(修改的先序树遍历)问题

    我的第一篇文章在这里 看来这是一个变得明智的地方 我目前正在进行一些测试 第一次尝试使用 MPTT 修改的预序树遍历 方法在 PHP 的帮助下将数据存储在 Mysql 数据库中 但是 我试图找到最注重性能的方法来获取特定级别上的所有列表元素
  • 为什么 .Net 词典中的条目是按加法顺序排列的?

    我刚刚看到这种行为 我对此感到有点惊讶 如果我向字典中添加 3 或 4 个元素 然后执行 For Each 来获取所有键 它们将以我添加的顺序出现 这让我感到惊讶的原因是字典内部应该是一个哈希表 所以我希望事情能以任何顺序出现 按键的哈希排
  • 二维数组中的寻路

    假设我有这个二维数组地图 0 0 0 0 7 1 1 1 1 1 1 1 1 0 7 7 7 7 1 1 1 24 1 1 1 1 0 7 24 24 24 24 24 24 24 1 1 3 1 0 7 23 23 23 23 23 23
  • 初始化 HashMap 的最佳方法

    我通常会这样做 HashMap
  • 在 Python 中进行模糊键查找的最佳方法?

    我遇到一个问题 我需要在哈希映射中进行模糊查找 即返回与最接近查询的键相对应的值 在我的例子中是通过 Levenshtein 距离测量的 我目前的方法是子类化dict使用特殊的查找方法计算所有键的编辑距离 然后返回得分最低的键的值 基本上是
  • Delphi 5 的哈希表实现 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 您知道 Delphi 5 的良好且免费的哈希表实现吗 我需要在哈希表中组织大量数据 并且我有点担心在网
  • 解释这段代码的工作原理;子进程如何返回值以及在哪里返回值?

    我不明白子进程如何返回该值以及返回给谁 输出为 6 7 问题来源 http www cs utexas edu mwalfish classes s11 cs372h hw sol1 html http www cs utexas edu
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • 如何从 Trie 中检索给定长度的随机单词

    我有一个简单的 Trie 用来存储大约 80k 长度为 2 15 的单词 它非常适合检查字符串是否是单词 但是 现在我需要一种获取给定长度的随机单词的方法 换句话说 我需要 getRandomWord 5 来返回 5 个字母的单词 所有 5
  • 添加到列表时有没有办法避免循环?

    我想知道这样的代码 List
  • 如何将列表转换为地图?

    最近我和一位同事讨论了转换的最佳方式是什么List to Map在 Java 中 这样做是否有任何具体的好处 我想知道最佳的转换方法 如果有人可以指导我 我将非常感激 这是个好方法吗 List
  • Scheme (Lisp) 中树的深度反转

    我对Scheme中的基本树数据结构进行了深度逆向 define deep reverse t cond null t not pair t t else cons deep reverse cdr t deep reverse car t
  • SQL 中的链表

    在 MySQL 数据库中存储链接列表的最佳方法是什么 这样插入就很简单 即 您不必每次都重新索引一堆内容 并且可以轻松地按顺序拉出列表 使用 Adrian 的解决方案 但不是增加 1 而是增加 10 甚至 100 然后可以按照要插入的内容之
  • python数据结构(类似设置)在添加重复项时抛出异常

    我正在寻找一种在添加重复元素时会引发异常的数据结构 我发现的最接近的是collections Counter gt gt gt from collections import Counter as counter gt gt gt c co

随机推荐