【发布时间】:2019-02-17 01:27:20
【问题描述】:
尝试用python编写dijkstras。无法修改元组时,如何实现 O(logn) 中的递减键操作?
我正在编写一个 sn-p 来解决邻接列表上的 dijkstras,并且需要优先级队列实现。我目前正在将 (priority, value) 的元组传递给 pq,以便 heapify 为我处理推送和弹出。但是,我不能修改元组,所以我不能有效地降低任何项目的优先级,必须弹出所有项目,直到找到我需要的项目,然后将所有项目读取到 pq,这使得时间复杂度 O(V^ 2)。有什么方法可以修改此代码,使 reductionKey 操作在 O(logn) 时间内工作?最好不涉及类。我不能用列表代替元组;否则它不会堆积起来
def decrease_key(pq, v, val):
li = []
u = heapq.heappop(pq)
while u[1] is not v:
li.append(u)
u = heapq.heappop(pq)
for l in li:
heapq.heappush(pq, l)
heapq.heappush(pq, (val, v))
def dijkstra(G, src, dist, V):
for v in range(V):
dist[v] = float('inf')
dist[src] = 0
pq = []
for k, v in dist.items():
pq.append((v, k))
while pq:
u = heapq.heappop(pq)[1]
for v, w in G[u]:
if dist[u] + w < dist[v]:
dist[v] = dist[u] + w
decrease_key(pq, v, dist[v])
O(n^2) 与所需 O(nlogn)
【问题讨论】:
-
不使用
heapq,但对于Dijkstra,您可以多次入队。 -
添加元素的数量不会严重增加时间吗?
-
不,二进制堆仍然是 O(E log V)。虽然额外的空间从 O(V) 到 O(E),但是省略父指针可能会抵消性能增益。减少密钥支持与在 o(log V) 时间内支持它的堆更相关。
-
猜猜没有出路,除非我想写自己的堆。谢谢!
标签: python algorithm graph-algorithm priority-queue dijkstra