python BFS最短路径问题

在一个带权重的图中,我们求从任意一个节点到其他节点的最短距离

在这个题目,我们可以使用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延伸的最短路径问题

如有错误请大神在评论区指出

我是小鹏,祝您幸福

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鹏在哪儿呢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值