堆是否支持修改其元素?

时间:2011-02-23 02:32:40

标签: python heap a-star

这是我的情景。我想实现A *(在Python中)而不必求助于线性时间最小值或在操作中。我需要一个堆才能有效地获得最低重量的项目。

我的直接反应是'简单!我会用heapq!'然后我发现生活很少像我们希望的那样简单。事实证明,这种策略对于A *的关键点之一来说并不是最理想的。在考虑孩子时,我需要偶尔更新已经在堆上的孩子的分数。

对于那些A *的记忆有点失效的人来说,它的要点是我想要一个元素,修改它的权重,并修改堆以反映变化,所有都在子线性时间内。

有什么建议吗?

3 个答案:

答案 0 :(得分:4)

出于复杂性目的,您可能想要尝试二项式或Fibonacci堆;似乎在Python中有两种实现,但没有生产级库。但是,二进制或d-ary堆在实践中可能会更快。 heapq页面提到了如何进行更新(保留对您插入堆中的项的引用,将其标记为无效,然后插入新版本)。但是,有更快的算法可以在更新后维护堆属性。请查看http://en.wikipedia.org/wiki/D-ary_heap以获取用于快速更新的算法,但您可能需要在数组顶部实现自己的堆。

答案 1 :(得分:0)

确实,heapqQueue.PriorityQueue中的堆函数都不是很有用。它可能需要大约相等的时间A:在你的博客上写一个咆哮或B:自己实现一个。

答案 2 :(得分:0)

我总是最终实现我自己的Heap类型版本,原因是你实际上无法在Heap中搜索,而所有有效的方法都需要“指向元素的指针”作为输入。

通常,我将Heap实现为Items的非结构化容器和Items的指针(或多个)的组合。如果您在项目中保留指向堆位置的指针,则您有一个直接的双向链接: a)给定一个Heap元素(例如,由extractMin返回,或者在比较期间):取消引用指针,你就得到了你的项目。 b)给定一个Item(例如通过Graph算法的邻接列表):将指针传递给你想要的任何更新函数。

当然,这会导致空间开销(每个项目增加2个指针/整数),但它会使Heap重组变得非常便宜(交换几个指针而不是交换整个项目),这反过来又增加了一些额外的痛苦。卫星数据到您的物品。