免责声明:我确实认为这不是类似问题的重复。我已经读过这些,他们(大多数)建议使用堆或优先级队列。我的问题更多的是“我不明白那些在这种情况下会如何起作用”。
简而言之:
我指的是典型的A *(A-star)寻路算法,如维基百科上所述(例如):
https://en.wikipedia.org/wiki/A*_search_algorithm
更具体地说,我想知道什么是最好的数据结构(可以是一个众所周知的数据结构,或者它们的组合),这样你就不会在任何操作上获得O(n)性能该算法需要在打开的列表上执行。
据我所知(主要来自维基百科文章),需要在公开名单上完成的操作如下:
此列表中的元素必须是具有以下属性的Node实例:
鉴于这些,操作是:
据我所知,使用堆或优先级队列打开列表的问题是:
此外,如果我们创建一个自定义数据结构,例如使用Hashtable(具有位置作为键)和优先级队列的结构,我们仍然会有一些操作需要对这两者中的任何一个进行次优处理:为了保持它们同步(两者都应该有相同的节点),对于给定的操作,该操作在其中一个数据结构上始终是次优的:按位置添加或删除节点在Hashtable上会很快但在优先级上会很慢队列。删除具有最低F分数的节点将在优先级队列上快速但在Hashtable上缓慢。
我所做的是为使用其位置作为键的节点制作自定义Hashtable,同时跟踪具有最低F分数的当前节点。添加新节点时,会检查其F分数是否低于当前存储的最低F分数节点,如果是,则替换它。当您想要删除节点(无论是按位置还是最低F得分)时,会出现此数据结构的问题。在这种情况下,为了更新持有当前最低F分数节点的字段,我需要遍历所有剩余节点,以便找到现在具有最低F分数的节点。
所以我的问题是:有没有更好的方法存储这些?
答案 0 :(得分:1)
您可以在不显示慢速操作的情况下组合散列表和堆。
将哈希表映射到堆中的索引而不是节点。
对堆的任何更新都可以自动同步(这需要堆了解哈希表,因此这是侵入性的,而不仅仅是两个现成实现的包装器)到具有更多更新的哈希表(每个O(1),显然)作为在堆中移动的项目数,当然只有log n
项可以移动插入,删除最小或更新密钥。哈希表找到节点(在堆中)以更新A *的父更新/ G更改步骤的密钥,这样也很快。