当前位置: 首页 > article >正文

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)

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

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


http://www.kler.cn/news/343414.html

相关文章:

  • python中的数组模块numpy(一)(适用物联网数据可视化及数据分析)
  • 【VUE】defineProperty和proxy的区别
  • 股市和期市历史分钟以及均线策略高级用法
  • 1.GoLang概述开发环境
  • 杂谈--Linux是什么用途?
  • 【java应用系统连接自有https证书(无法验证)的minio服务时报错问题处理过程】
  • JAVA中线程的生命周期
  • 将JSON的格式数据存储到数据库中
  • Jetpack Compose 页面跳转 - 导航Navigation使用和封装
  • 共识算法Raft
  • 【新书】使用生成式人工智能和Python开始数据分析
  • 回归涉及的函数
  • C语言-了解程序环境和预处理看这一篇(超详解)
  • std::future::then的概念和使用方法
  • Java SSL使用Openssl ECC加密生成证书遇到的坑
  • Python和C++及MATLAB低温磁态机器学习模型
  • 【解决办法】git clone报错unable to access ‘xxx‘: SSL certificate problem
  • 第19周JavaWeb编程实战-MyBatis实现OA系统 面试题解析
  • Go语言学习代码记录
  • C++继承深度剖析:从理论到实践的跨越