如何使用吉特拉斯算法获得一源两目的地的最短距离?



我使用了一个已经可用的代码,它返回源和目的地之间的最短距离,尝试更新代码以获得源和两个目的地之间的最短路径,基于此我可以比较两条路径。但这似乎不起作用。如果能提供任何帮助,我将不胜感激。

代码如下:

def dijkstra(graph,start,goal):
minimumContainmentZones = {}
predecessor = {}
unseenNodes = graph
infinity = 9999999
path = []
for node in unseenNodes:
minimumContainmentZones[node] = infinity
minimumContainmentZones[start] = 0

while unseenNodes:
minNode = None
for node in unseenNodes:
if minNode is None:
minNode = node
elif minimumContainmentZones[node] < minimumContainmentZones[minNode]:
minNode = node

for childNode, weight in graph[minNode].items():
if weight + minimumContainmentZones[minNode] < minimumContainmentZones[childNode]:
minimumContainmentZones[childNode] = weight + minimumContainmentZones[minNode]
predecessor[childNode] = minNode
unseenNodes.pop(minNode)

currentNode = goal
while currentNode != start:
try:
path.insert(0,currentNode)
currentNode = predecessor[currentNode]
except KeyError:
print('Path not reachable')
break
path.insert(0,start)
if minimumContainmentZones[goal] != infinity:
return(goal,minimumContainmentZones[goal],str(path))



if __name__=="__main__":
graph = {'a':{'b':5,'c':3,'d':2},'b':{'a':3,'e':11,'f':12},'c':{'a':5,'f':7},'d':{'a':2,'f':8,'g':5},'e':{'b':11,'f':3,'h':3},'f':{'b':12,'c':7,'d':8,'e':3,'g':4,'h':7,'i':5,'k':4},'g':{'d':5,'f':4,'k':5},'h':{'e':3,'f':7,'j':2},'i':{'f':5,'j':3} ,  'j':{'h':2,'i':3,'k':6}  ,'k':{'g':5,'f':4,'j':6} }  
a,b,c=dijkstra(graph, 'a', 'h')
d,e,f=dijkstra(graph, 'a', 'j')
print(a,b,c)
print(d,e,f)

给出错误:

Path not reachable
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-93-bc57edb9feb6> in <module>
40     graph = {'a':{'b':5,'c':3,'d':2},'b':{'a':3,'e':11,'f':12},'c':{'a':5,'f':7},'d':{'a':2,'f':8,'g':5},'e':{'b':11,'f':3,'h':3},'f':{'b':12,'c':7,'d':8,'e':3,'g':4,'h':7,'i':5,'k':4},'g':{'d':5,'f':4,'k':5},'h':{'e':3,'f':7,'j':2},'i':{'f':5,'j':3} ,  'j':{'h':2,'i':3,'k':6}  ,'k':{'g':5,'f':4,'j':6}      }
41     a,b,c=dijkstra(graph, 'a', 'h')
---> 42     d,e,f=dijkstra(graph, 'a', 'j')
43     print(a,b,c)
44     print(d,e,f)
<ipython-input-93-bc57edb9feb6> in dijkstra(graph, start, goal)
32             break
33     path.insert(0,start)
---> 34     if minimumContainmentZones[goal] != infinity:
35         return(goal,minimumContainmentZones[goal],str(path))
36 
KeyError: 'j'

问题是第一次调用该函数时,通过删除节点来修改图。然后,第二次调用它时,预期的节点不再存在了!危险来自于使用unseenNodes.pop()

提醒一下,Python中的赋值是通过引用完成的,所以 行
unseenNodes = graph

创建对同一图的另一个引用,而不是该图的副本。


这里有一个方法来修复它:实际上做一个副本。

在脚本的顶部,使用这一行:

from copy import deepcopy

现在,你说的unseenNodes = graph,把它改成:

unseenNodes = deepcopy(graph)
这里的好处是,您可以随意修改新对象,而不会影响外部作用域的图。你在它上面调用你的函数时,它将是相同的图形。

最新更新