python 实现bfs 最短路径算法

bfs 最短路径算法介绍

BFS(广度优先搜索,Breadth-First Search)是一种用于图遍历或搜索树或图的算法。尽管BFS本身不直接计算最短路径,但它可以用来实现某些情况下的最短路径算法,特别是在无权图(即所有边的权重都相等)中。

在无权图中,从源点到任何其他顶点的最短路径就是边数最少的路径。由于BFS总是首先访问离源点最近的节点(基于边的数量),因此它天然地可以用来找到源点到所有其他节点的最短路径(基于边的数量)。

BFS算法的基本思想

初始化:选择一个源点,并将其标记为已访问。创建一个队列,并将源点加入队列。

循环:当队列不为空时,进行循环。从队列中移除一个节点,并检查它的所有邻接点。对于每一个邻接点:

如果邻接点未被访问过,则将其标记为已访问,并将其加入队列。
(可选)记录到达每个邻接点的路径或步数。

结束:当队列为空时,算法结束。所有从源点可达的节点都已被访问,且对于无权图,已经找到了从源点到这些节点的最短路径(基于边的数量)。

BFS实现最短路径的示例

考虑一个简单的无权图,使用邻接表表示。我们需要找到从节点S到所有其他节点的最短路径(基于边的数量)。

from collections import deque

# 图的邻接表表示
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E'],
}

def bfs(graph, start):
    visited = set()  # 访问过的节点
    queue = deque([(start, [start])])  # 队列中的元素是(节点, 从起点到该节点的路径)
    
    while queue:
        vertex, path = queue.popleft()
        if vertex not in visited:
            visited.add(vertex)
            print(f"从 {start}{vertex} 的最短路径是: {path}")
            for neighbour in graph[vertex]:
                if neighbour not in visited:
                    queue.append((neighbour, path + [neighbour]))

bfs(graph, 'A')

注意:上述代码假设了所有边的权重都是1,且没有循环边(即不是有向图且没有环)。对于有权图,BFS无法直接用来找到最短路径(基于权重),这时应该使用Dijkstra算法(对于非负权重)或Bellman-Ford算法(对于可能包含负权重的图)。

bfs 最短路径算法python实现样例

下面是使用Python实现BFS最短路径算法的示例代码:

from queue import Queue

def bfs_shortest_path(graph, start, end):
    # 创建一个队列并将起始节点入队
    queue = Queue()
    queue.put([start])

    while not queue.empty():
        # 从队列中取出一条路径
        path = queue.get()
        # 获取路径的最后一个节点
        node = path[-1]

        # 如果当前节点是目标节点,则返回路径
        if node == end:
            return path

        # 遍历当前节点的相邻节点
        for adjacent_node in graph.get(node, []):
            # 如果相邻节点未在路径中,则将路径拓展并入队
            if adjacent_node not in path:
                new_path = list(path)
                new_path.append(adjacent_node)
                queue.put(new_path)

    # 如果没有找到路径,则返回空列表
    return []

# 测试示例
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}

start_node = 'A'
end_node = 'F'

shortest_path = bfs_shortest_path(graph, start_node, end_node)
print(shortest_path)

在这个示例中,我们首先创建一个队列,然后将起始节点入队。然后我们进入一个循环,直到队列为空。在每一次循环中,我们从队列中取出一条路径,并获取路径的最后一个节点。如果最后一个节点是目标节点,则我们已经找到了最短路径,可以返回它。

否则,我们遍历最后一个节点的相邻节点,并将相邻节点拓展到路径中,并入队。我们还需要检查路径中是否已经包含了相邻节点,以避免形成环路。如果我们在循环结束后都没有找到目标节点,则返回一个空列表。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

luthane

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

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

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

打赏作者

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

抵扣说明:

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

余额充值