我想使用堆数据结构实现Dijkstra的最短路径算法。为此,我正在寻找一个堆,当您更改元素的优先级时,它会根据需要自动向上和向下筛选成员。
到目前为止,我已经尝试了queue.PriorityQueue和Stutzbach的heapdict,但从以下测试中看,似乎都没有这个属性:
import queue
from heapdict import heapdict
import pytest
class Node(object):
def __init__(self, d):
self.d = d
def __lt__(self, other):
return self.d < other.d
def test_priority_queue():
node1 = Node(d=5)
node2 = Node(d=10)
Q = queue.PriorityQueue()
Q.put(node1)
Q.put(node2)
node2.d = 2
assert Q.get().d == 2 # Fails because 5 != 2
def test_heapdict():
node1 = Node(d=5)
node2 = Node(d=10)
hd = heapdict()
hd[1] = node1
hd[2] = node2
node2.d = 2
index, node = hd.popitem()
assert node.d == 2 # Fails because 5 != 2
if __name__ == "__main__":
pytest.main([__file__])
当我将node2
的优先级更新为2
而不是10
时,它会自动移至堆顶部,以便get
/ {{ 1}}方法返回它。我想创建一个数据结构,以便通过类似的测试。
更新
执行类似操作的对象是pqdict。但是,根据its documentation,它也不适用于可变对象:
价值可变性。如果将可变对象用作
popitem
中的值,则对这些对象状态的更改可能会破坏优先级队列。如果发生这种情况,可以通过调用pqdict
来修复数据结构。 (但你可能不应该首先使用可变值。)