在Python中,如何实现一个最小优先级队列,在更改其中一个成员的优先级时维护堆不变量?

时间:2017-09-26 09:44:02

标签: python algorithm heap observers

我想使用堆数据结构实现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}}方法返回它。我想创建一个数据结构,以便通过类似的测试。

然而,我正在努力想出一个关于如何实现这一点的高层次想法。它可能应该遵循observer pattern并使用property属性,但具体如何?

更新

执行类似操作的对象是pqdict。但是,根据its documentation,它也不适用于可变对象:

  

价值可变性。如果将可变对象用作popitem中的值,则对这些对象状态的更改可能会破坏优先级队列。如果发生这种情况,可以通过调用pqdict来修复数据结构。 (但你可能不应该首先使用可变值。)

0 个答案:

没有答案