我在Python中实现了两个Dijkstra算法(方法),这是我从这个http://jpython.blogspot.com/2015/10/dijkstra-algorithm.html源获取的第一个方法,第二个是由我创建的,它更适合C ++风格(带有检查和放松) - 我喜欢的方法。第一个Dijkstra方法有效,但第二个dijkstra2总是返回1e9。第二种方法有什么问题。
from heapq import *
def Dijkstra(graph, source):
dist = [None] * len(graph)
queue = [(0, source)]
while queue:
c_dist, u = heappop(queue)
if dist[u] is None:
dist[u] = c_dist
for v, length in graph[u].items():
if dist[v] is None:
heappush(queue, (c_dist + length, v))
return [-1 if x is None else x for x in dist]
def dijkstra2( graph, source):
dist = [1e9] * len(graph)
queue = [(0, source)]
while queue:
c_dist, u = heappop(queue)
if c_dist > dist[u]:
continue
for v, length in graph[u].items():
if dist[v] > dist[u] + length:
dist[v] = dist[u] + length
return [-1 if x is 1e9 else x for x in dist]
graph = {
0: { 1:2, 2:4, 3:1 },
1: { 2:1, 3:3 },
2: { 4: 7},
3: { 2: 2 },
4: { 0:2, 3:3 },
5: {}
}
source = 0
print (Dijkstra(graph, source))
答案 0 :(得分:3)
您的代码中有3个问题:
正如chrisz已经指出的那样,您需要将v
添加到队列中,否则您只会在循环中执行一次传递。
由于在将节点放入队列时更新dist中的值,而不是在弹出它们时更新,您需要在开头更改源的距离
由于您需要使用1e9
而不是-1
,因此不会执行最后x==1e9
和x is 1e9
之间的转换。
您可以在任何python控制台中检查:
x=1e9
x is 1e9
返回False
。
这是一个完整的工作代码:
def dijkstra2( graph, source):
INFINITY = 1e9
dist = [INFINITY] * len(graph)
queue = [(0, source)]
dist[source]= 0
while queue:
c_dist, u = heappop(queue)
if c_dist > dist[u]:
continue
for v, length in graph[u].items():
if dist[v] > dist[u] + length:
dist[v] = dist[u] + length
heappush(queue, (dist[v], v))
return [-1 if x==INFINITY else x for x in dist]