如何转换基于"无"的Dijsktra算法的Python实现?距离" Infinity"距离

时间:2018-01-05 06:23:19

标签: python-3.x algorithm graph dijkstra

我在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))

1 个答案:

答案 0 :(得分:3)

您的代码中有3个问题:

  • 正如chrisz已经指出的那样,您需要将v添加到队列中,否则您只会在循环中执行一次传递。

  • 由于在将节点放入队列时更新dist中的值,而不是在弹出它们时更新,您需要在开头更改源的距离

  • 由于您需要使用1e9而不是-1,因此不会执行最后x==1e9x 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]