更新优先级队列python-Dijkstras算法
我想了解在以下工作和完成的代码中,为什么在更新pq_更新时,它被写为pq_更新[Neighbor][1] 与其写pq_更新[Neighbor](我就是这么做的),它似乎并没有改变任何东西,为什么要包括它 多谢各位更新优先级队列python-Dijkstras算法,python,dictionary,graph,Python,Dictionary,Graph,我想了解在以下工作和完成的代码中,为什么在更新pq_更新时,它被写为pq_更新[Neighbor][1] 与其写pq_更新[Neighbor](我就是这么做的),它似乎并没有改变任何东西,为什么要包括它 多谢各位 导入heapq def dijkstra(图表,开始): 距离={顶点:图中顶点的浮点('inf')} pq=[] pq_更新={} 距离[起点]=0 对于顶点,以距离为单位的值。项() 条目=[顶点,值] heapq.heappush(pq,条目) pq_更新[顶点]=条目 而pq:
导入heapq
def dijkstra(图表,开始):
距离={顶点:图中顶点的浮点('inf')}
pq=[]
pq_更新={}
距离[起点]=0
对于顶点,以距离为单位的值。项()
条目=[顶点,值]
heapq.heappush(pq,条目)
pq_更新[顶点]=条目
而pq:
getmin=heapq.heapop(pq)[0]
对于邻居,在图形[getmin]中显示距离。\n。项()
距离=距离[getmin]+距离
如果距离<距离[邻居]:
距离[邻居]=距离
pq#U更新[邻居][1]=距离#此行!!!
打印(距离)
返回距离
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
示例_图={
'U':{'V':2,'W':5,'X':1},
'V':{'U':2,'X':2,'W':3},
W:{'V':3,'U':5,'X':3,'Y':1,'Z':5},
'X':{'U':1,'V':2,'W':3,'Y':1},
'Y':{'X':1,'W':1,'Z':1},
'Z':{'W':5,'Y':1},
}
dijkstra(示例_图,'X')
注意:您的实现已损坏,无法正确实现Dijkstra。下面将详细介绍
pq\u更新
字典包含列表,每个列表有两个条目:
for vertex, value in distances.items():
entry = [vertex, value]
heapq.heappush(pq, entry)
pq_update[vertex] = entry
因此,pq\u update[neighbor]
是一个包含顶点和距离的列表。您希望更新距离,而不是替换[顶点,值]
列表,因此使用pq\u update[neighbor][1]
请注意,条目
列表也与heapq
共享。pq
堆引用了相同的列表对象,因此对pq\u update[neightbor][1]
的更改也将在堆上仍要处理的条目中可见
当您直接指定给pq\u update[neighbor]
时,您将删除该连接
您看不到任何差异的原因是因为该算法的实现实际上已经中断,因为堆没有正确使用。堆按您推入的列表项中的第一个值按第一个排序。在您的代码中,这是节点名称,而不是距离,并且当列表项中的距离更改时,项目的heapq顺序永远不会更新。由于heapq未正确使用,因此始终按字母顺序遍历节点
要正确使用heapq
,您需要将边长度放在第一位,并且不更改堆上的值;如果使用元组,就不能意外地这样做。实际上,您只需要将节点推送到您到达的堆上;对于某些节点(通过多条路径到达),您将得到多个条目,但heapq
仍将首先显示到该节点的最短路径。只需保留一组已访问的节点,就可以跳过更长的路径。关键是,在访问较长路径之前,先访问给定节点的较短路径,而无需修改heapq项即可实现这一点
您可以将函数(使用更好的变量名)重新写入:
def dijkstra(图形,开始):
“”“访问所有节点并从一开始计算到每个节点的最短路径”“”
队列=[(0,开始)]
距离={开始:0}
访问=设置()
排队时:
_,node=heapq.heapop(队列)#(距离,节点),忽略距离
如果访问了中的节点:
持续
已访问。添加(节点)
距离=距离[节点]
对于邻居,图[node]中的邻居距离。项()
如果访问了邻居:
持续
相邻距离+=距离
如果邻居距离
注意:您的实现已损坏,无法正确实现Dijkstra。下面将详细介绍
pq\u更新
字典包含列表,每个列表有两个条目:
for vertex, value in distances.items():
entry = [vertex, value]
heapq.heappush(pq, entry)
pq_update[vertex] = entry
因此,pq\u update[neighbor]
是一个包含顶点和距离的列表。您希望更新距离,而不是替换[顶点,值]
列表,因此使用pq\u update[neighbor][1]
请注意,条目
列表也与heapq
共享。pq
堆引用了相同的列表对象,因此对pq\u update[neightbor][1]
的更改也将在堆上仍要处理的条目中可见
当您直接指定给pq\u update[neighbor]
时,您将删除该连接
您看不到任何差异的原因是因为该算法的实现实际上已经中断,因为堆没有正确使用。堆按您推入的列表项中的第一个值按第一个排序。在您的代码中,这是节点名称,而不是距离,并且当列表项中的距离更改时,项目的heapq顺序永远不会更新。由于heapq未正确使用,因此始终按字母顺序遍历节点
要正确使用heapq
,您需要将边长度放在第一位,并且不更改堆上的值;如果使用元组,就不能意外地这样做。实际上,您只需要将节点推送到您到达的堆上;对于某些节点(通过多条路径到达),您将得到多个条目,但heapq
仍将首先显示到该节点的最短路径。只需保留一组已访问的节点,就可以跳过更长的路径。关键是,在访问较长路径之前,先访问给定节点的较短路径,而无需修改heapq项即可实现这一点
您可以重新编写您的函数