在一个带权重的图中,我们求从任意一个节点到其他节点的最短距离
在这个题目,我们可以使用bfs算法
首先,我们要引入一个队列,优先队列,他是一个神奇的队列,他会在使用他特定的pop的时候自动弹出数字最小的元素
import heapq
grout=[]
heapq.heappush(grout,(100,'c'))
heapq.heappush(grout,(88,'b'))
heapq.heappush(grout,(56,'a'))
print(grout)
xx=heapq.heappop(grout)
print(xx)
print(grout)
xx=heapq.heappop(grout)
print(xx)
print(grout)
从代码我们可以看出,在我们给他添加元素进去以后,他会自动排序,当然,在我们print查看时 发现他并没有排序,但其实他是安装自己内置的排序方式排序了,当我们heappop时,他会自动弹出优先最高的56>88>100
好,有了这个队列我们开始想办法写代码,最开始我们需要把我这个图用一个数据结构装起来,还要标明他的路径权重,相邻节点,所以我们可以选择字典
graph = {
"A": {"B": 5, "C": 1},
"B": {"A": 5, "C": 2, "D": 1},
"C": {"A": 1, "B": 2, "D": 4, "E": 8},
"D": {"B": 1, "C": 4, "E": 3, "F": 6},
"E": {"C": 8, "D": 3},
"F": {"D": 6}
}
字典选好以后,我们创建优先队列,我们假设我们根节点是A,求到其他节点的最短距离
最开我们在里面加入开始的根节点,带上路径,因为A到A没有距离,这里用0表示
然后我们拿这个优先队列开始循环,我们把A拿出来,然后找到和他相连的其他节点,这里是B,C
然后我们把B,C放进去,并且这里注意,进入队列以后的节点要拿前节点与A的距离加上自己本身与这个节点的距离,因为第一个是0,所以没有变化
然后因为优先队列自动排序问题所以c会在b前面
然后弹出c,再放入c的相邻节点,但是c的相邻有a,b,d,e,难道全部放进去?
当然不行,为了避免走回头路就是不走回a,我们可以再创建一个队列,里面放拿出来的元素,就是已经见过了走过了,不能在走的元素,我们暂时叫n,然后把其他点放进去就一直这么循环反复,直到全部点拿出
当然在这循环中,会有重复点出现,像现在的(B,2),他在进入n以后,在以后循环中总会被拿出来,但是他已经在前面做完了,所以直接比较大小后排除开外
最后结果的n为
这样我们就可以得到这些节点与根节点最短路径是多少了
但是如果我们需要求的如何走过来的,那么还需要多创建一个字典,在优先队列一个个拿出来的时候进行记录即可具体操作见代码
import math
import heapq
graph = {
"A": {"B": 5, "C": 1},
"B": {"A": 5, "C": 2, "D": 1},
"C": {"A": 1, "B": 2, "D": 4, "E": 8},
"D": {"B": 1, "C": 4, "E": 3, "F": 6},
"E": {"C": 8, "D": 3},
"F": {"D": 6}
}
#防止38段下标出界,把根节点变0外,还要把其他点变成正无穷
def init_distance(graph, s):
distance = {s: 0}
for vertex in graph:
if vertex != s:
distance[vertex] = math.inf
return distance
def bfs(npp, x):
# 优先队列
pqueue = []
heapq.heappush(pqueue, (0, x))
# 已经走过的节点
seen = set()
#记录路径的字典
parent = {x: None}
distance = init_distance(graph, x)
while (len(pqueue) > 0):
pair = heapq.heappop(pqueue)
dist = pair[0]
vertex = pair[1]
seen.add(vertex)
nodes = graph[vertex].keys()
for w in nodes:
if w not in seen:
if dist + graph[vertex][w] < distance[w]:
heapq.heappush(pqueue, (dist + graph[vertex][w], w))
parent[w] = vertex
distance[w] = dist + graph[vertex][w]
return parent, distance
p, d = bfs(graph, "A")
print(p)
print(d)
这就是bfs延伸的最短路径问题
如有错误请大神在评论区指出
我是小鹏,祝您幸福