【Python搜索算法】广度优先搜索(BFS)算法原理详解与应用,示例+代码

目录

1 广度优先搜索    

2 应用示例

2.1 迷宫路径搜索

2.2 社交网络中的关系度排序

2.3 查找连通区域


1 广度优先搜索    

        广度优先搜索(Breadth-First Search,BFS)是一种图遍历算法,用于系统地遍历或搜索图(或树)中的所有节点。BFS的核心思想是从起始节点开始,首先访问其所有相邻节点,然后逐层向外扩展,逐一访问相邻节点的相邻节点,以此类推。这意味着BFS会优先探索距离起始节点最近的节点,然后再逐渐扩展到距离更远的节点。BFS通常用于查找最短路径、解决迷宫问题、检测图是否连通以及广泛的图问题。

BFS算法的步骤如下:

  1. 初始化:选择一个起始节点,将其标记为已访问,并将其放入队列中(作为起始节点)。

  2. 进入循环:重复以下步骤,直到队列为空。 a. 从队列中取出一个节点。 b. 访问该节点。 c. 将所有未访问的相邻节点加入队列。 d. 标记已访问的节点,以避免重复访问。

  3. 结束循环:当队列为空时,表示已经遍历完整个图。

以下是BFS的算法原理详解和一个应用示例:

算法原理:

        BFS的工作原理是通过队列数据结构来管理待访问的节点。它从起始节点开始,然后逐一访问该节点的相邻节点,并将它们加入队列。然后,它从队列中取出下一个节点进行访问,以此类推。这确保了节点按照它们的距离从起始节点逐层遍历,因此BFS可以用于查找最短路径。

        BFS是一个宽度优先的搜索,它在查找最短路径等问题中非常有用。它不会陷入深度过深的路径,因为它会优先探索距离起始节点更近的节点。

2 应用示例

2.1 迷宫路径搜索

        假设有一个迷宫,其中包含墙壁和通道,您希望找到从起始点到终点的最短路径。BFS是解决这类问题的理想选择。

示例迷宫:

S 0 0 1 1 1
1 1 0 1 0 1
1 0 0 0 0 1
1 1 1 1 0 1
1 0 0 1 0 1
1 1 1 1 1 E
  • S 表示起始点
  • E 表示终点
  • 0 表示可以通过的通道
  • 1 表示墙壁

 使用BFS,您可以找到从起始点到终点的最短路径,如下所示:

  1. 从起始点 S 开始,将其加入队列。
  2. 逐层遍历节点,首先访问距离 S 最近的节点。
  3. 在每一步中,将所有可以通过的相邻节点加入队列,同时标记已访问的节点。
  4. 继续这个过程,直到到达终点 E

BFS会优先探索距离 S 最近的通道,因此它会找到从 SE 的最短路径。在上面的迷宫中,BFS将找到一条最短路径,经过标有数字 0 的通道,最终到达终点 E。这是BFS在寻找最短路径问题中的一个实际应用示例。

示例:

import matplotlib.pyplot as plt
from collections import dequedef bfs_shortest_path(maze, start, end):# 定义四个方向移动的偏移量,分别是上、下、左、右directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]rows, cols = len(maze), len(maze[0])# 创建队列用于BFSqueue = deque([(start, [start])])visited = set()while queue:(x, y), path = queue.popleft()visited.add((x, y))if (x, y) == end:return path  # 找到了最短路径for dx, dy in directions:new_x, new_y = x + dx, y + dyif 0 <= new_x < rows and 0 <= new_y < cols and maze[new_x][new_y] == 0 and (new_x, new_y) not in visited:new_path = path + [(new_x, new_y)]queue.append(((new_x, new_y), new_path))return None  # 没有找到路径def draw_maze(maze, path=None):rows, cols = len(maze), len(maze[0])# 创建一个图形对象fig, ax = plt.subplots()# 绘制迷宫for x in range(rows):for y in range(cols):if maze[x][y] == 0:ax.add_patch(plt.Rectangle((y, -x - 1), 1, 1, facecolor="white"))else:ax.add_patch(plt.Rectangle((y, -x - 1), 1, 1, facecolor="gray"))# 绘制路径(如果存在)if path:for x, y in path:ax.add_patch(plt.Rectangle((y, -x - 1), 1, 1, facecolor="green"))# 设置坐标轴ax.set_aspect("equal")ax.set_xticks(range(cols))ax.set_yticks(range(-rows, 0))ax.set_xticklabels([])ax.set_yticklabels([])plt.grid(True)plt.show()# 示例迷宫,0表示通道,1表示墙壁
maze = [[0, 0, 0, 1, 1, 1],[1, 1, 0, 1, 0, 1],[1, 0, 0, 0, 0, 1],[1, 1, 1, 1, 0, 1],[1, 0, 0, 1, 0, 0],[1, 1, 0, 0, 1, 0]
]start = (0, 0)  # 起始点
end = (5, 5)  # 终点path = bfs_shortest_path(maze, start, end)draw_maze(maze, path)

2.2 社交网络中的关系度排序

        广度优先搜索(BFS)的排序应用示例之一是使用它在无权图中查找最短路径。在前面的示例中,我们已经展示了如何使用BFS查找迷宫中的最短路径。这是BFS的一个典型应用示例。

        另一个排序应用示例是社交网络中的关系度排序。在社交网络中,您可以使用BFS来确定您与其他用户之间的关系度,即您与其他用户之间的最短路径,或者共同的朋友数量。以下是一个简单的示例:

        假设您有一个社交网络,其中用户之间的关系用图表示,其中节点代表用户,边代表用户之间的关系。您想知道您与其他用户之间的关系度,并按关系度对用户进行排序。

import networkx as nx
import matplotlib.pyplot as plt
from collections import deque# 创建一个复杂的社交网络图
social_network = {'You': ['Alice', 'Bob', 'Claire', 'David'],'Alice': ['Diana', 'Eva', 'Frank'],'Bob': ['Eva', 'Frank', 'George'],'Claire': ['Diana', 'George', 'Hannah'],'David': ['Hannah'],'Diana': ['Eva', 'George'],'Eva': ['Frank'],'Frank': ['George', 'Hannah'],'George': ['Hannah'],'Hannah': [],
}def bfs_relationship_degree(graph, start):visited = set()queue = deque([(start, 0)])  # 用于存储节点和关系度relationship_degree = {}  # 存储关系度while queue:node, degree = queue.popleft()if node not in visited:visited.add(node)relationship_degree[node] = degreefor friend in graph[node]:if friend not in visited:queue.append((friend, degree + 1))return relationship_degree# 使用BFS查找关系度
your_name = 'You'
relationship_degree = bfs_relationship_degree(social_network, your_name)# 创建一个有向图
G = nx.DiGraph()# 添加节点和边
for user, degree in relationship_degree.items():G.add_node(user, degree=degree)for user in social_network:for friend in social_network[user]:G.add_edge(user, friend)# 绘制图形
pos = nx.spring_layout(G, seed=42)
labels = nx.get_node_attributes(G, 'degree')
nx.draw(G, pos, with_labels=True, node_size=1000, node_color='lightblue', font_size=10, font_color='black')
nx.draw_networkx_labels(G, pos, labels, font_size=10, font_color='black')
plt.title("复杂社交网络图")
plt.show()# 输出排序结果
sorted_users = sorted(relationship_degree.items(), key=lambda x: x[1])
for user, degree in sorted_users:print(f'{user}: 关系度 {degree}')

输出:

 输出:

You: 关系度 0
Alice: 关系度 1
Bob: 关系度 1
Claire: 关系度 1
David: 关系度 1
Diana: 关系度 2
Eva: 关系度 2
Frank: 关系度 2
George: 关系度 2
Hannah: 关系度 2

 这段代码的目的是使用广度优先搜索(BFS)算法来查找社交网络中您('You')与其他用户之间的关系度,并绘制社交网络图。

  1. 首先,定义了一个复杂的社交网络图,其中包括不同用户之间的关系。这个社交网络图存储在 social_network 字典中。

  2. bfs_relationship_degree 函数实现了BFS算法来查找您与其他用户之间的关系度。它从您开始,逐层查找与您相连接的用户,计算它们之间的关系度。结果存储在 relationship_degree 字典中。

  3. 创建一个有向图(DiGraph) G 以绘制社交网络图。

  4. 添加节点和边到图 G,其中节点代表用户,边代表用户之间的关系。此时,节点的颜色和大小被设置为 lightblue1000,并且边的颜色为 gray

  5. 使用 NetworkX 提供的布局算法 spring_layout 来确定节点的位置。

  6. 绘制图形,包括节点和边,以及节点上的标签。

  7. 输出用户的关系度排序结果,按照从您('You')到其他用户的关系度进行排序。

运行该代码将绘制出社交网络图,并输出用户的关系度排序结果。这可以帮助您可视化您与其他用户之间的关系,并查看谁与您更亲近。

2.3 查找连通区域

        在图像处理中,连通区域是由相邻像素组成的区域,具有相似的特性(如颜色或灰度)。BFS可以用来查找和标记这些连通区域。

import cv2
import numpy as np# 读取图像
image = cv2.imread('img.jpg', 0)  # 以灰度模式读取图像
ret, binary_image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)# 创建一个与图像大小相同的标记图
height, width = binary_image.shape
markers = np.zeros((height, width), dtype=np.int32)# 定义一个颜色映射
color_map = {1: (0, 0, 255),  # 红色2: (0, 255, 0),  # 绿色3: (255, 0, 0),  # 蓝色4: (0, 255, 255),  # 黄色# 您可以根据需要添加更多颜色
}# 连通区域计数
region_count = 0# 定义8个邻域的偏移
neighbor_offsets = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]# 开始查找连通区域
for y in range(height):for x in range(width):if binary_image[y, x] == 255 and markers[y, x] == 0:region_count += 1markers[y, x] = region_countqueue = [(y, x)]while queue:current_y, current_x = queue.pop(0)for dy, dx in neighbor_offsets:ny, nx = current_y + dy, current_x + dxif 0 <= ny < height and 0 <= nx < width and binary_image[ny, nx] == 255 and markers[ny, nx] == 0:markers[ny, nx] = region_countqueue.append((ny, nx))# 将连通区域标记为不同颜色
result_image = np.zeros((height, width, 3), dtype=np.uint8)
for y in range(height):for x in range(width):if markers[y, x] > 0:result_image[y, x] = color_map[markers[y, x]]# 显示结果图像
cv2.imshow('Connected Components', result_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

         这段代码首先读取了一个灰度图像(也可以使用彩色图像),将其转换为二值图像。然后,它使用BFS算法查找连通区域,对不同的连通区域进行标记,并将它们标记为不同的颜色。最后,它显示带有标记的结果图像。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/160935.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux Zabbix企业级监控平台+cpolar实现远程访问

文章目录 前言1. Linux 局域网访问Zabbix2. Linux 安装cpolar3. 配置Zabbix公网访问地址4. 公网远程访问Zabbix5. 固定Zabbix公网地址 前言 Zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。能监视各种网络参数&#xff0c;保证服务器系…

HTML三叉戟,标签、元素、属性各个的意义是什么?

&#x1f31f;&#x1f31f;&#x1f31f; 专栏详解 &#x1f389; &#x1f389; &#x1f389; 欢迎来到前端开发之旅专栏&#xff01; 不管你是完全小白&#xff0c;还是有一点经验的开发者&#xff0c;在这里你会了解到最简单易懂的语言&#xff0c;与你分享有关前端技术和…

【Java基础面试十二】、说一说你对面向对象的理解

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a; 说一说你对面向对象的理…

thinkphp5.1 获取缓存cache(‘cache_name‘)特别慢,php 7.0 unserialize 特别慢

thinkphp5.1 获取缓存cache(‘cache_name’)特别慢&#xff0c;php 7.0 unserialize 特别慢 场景&#xff1a; 项目中大量使用了缓存&#xff0c;本地运行非常快&#xff0c;二三百毫秒&#xff0c;部署到服务器后 一个表格请求就七八秒&#xff0c;最初猜想是数据库查询慢&am…

消息队列学习分享

消息队列学习 消息队列来解决问题 &#xff08;1&#xff09;异步处理 消息通知、日志管理、更新统计数据等步骤 &#xff08;2&#xff09;流量控制 如何避免过多的请求压垮我们的系统&#xff1f; 比如一个秒杀系统&#xff0c;网关在收到请求后&#xff0c;将请求放入…

Kotlin中的数值类型

在Kotlin中&#xff0c;Byte、Short、Int、Long、Float和Double是基本数据类型&#xff0c;用于表示不同范围和精度的数值。 Byte&#xff08;字节&#xff09;&#xff1a;Byte类型是8位有符号整数类型&#xff0c;取值范围为-128到127。在Kotlin中&#xff0c;可以使用字面值…

vscode工程屏蔽不使用的文件夹或文件的方法

一. 简介 vscode是一款 微软提供的免费的代码编辑软件。 对于 IMX6ULL-ALPHA开发板而言&#xff0c;NXP官方uboot一定会支持不止 IMX6ULL芯片的代码&#xff0c;也不止支持 一种架构&#xff0c;还支持其他芯片或架构的源码文件。 为了方便阅读代码&#xff0c;vscode软件可…

腾讯云我的世界mc服务器多少钱一年?

腾讯云我的世界mc服务器多少钱&#xff1f;95元一年2核2G3M轻量应用服务器、2核4G5M带宽优惠价218元一年、4核8G12M带宽轻量服务器446元一年&#xff0c;云服务器CVM标准型S5实例2核2G优惠价280元一年、2核4G配置服务器748元一年&#xff0c;腾讯云百科txybk.com分享腾讯云我的…

[LeetCode周赛复盘] 第 115 场双周赛20231014

[LeetCode周赛复盘] 第 115 场双周赛20231014 一、本周周赛总结100095. 上一个遍历的整数1. 题目描述2. 思路分析3. 代码实现 100078. 最长相邻不相等子序列 I1. 题目描述2. 思路分析3. 代码实现 100077. 最长相邻不相等子序列 II1. 题目描述2. 思路分析3. 代码实现 100029. 和…

【数据结构】排序--选择排序(堆排序)

目录 一 堆排序 二 直接选择排序 一 堆排序 堆排序(Heapsort)是指利用堆积树&#xff08;堆&#xff09;这种数据结构所设计的一种排序算法&#xff0c;它是选择排序的一种。它是 通过堆来进行选择数据。 需要注意的是排升序要建大堆&#xff0c;排降序建小堆。 直接选择排…

HEIC转jpg

下载imagemagick,安装 https://imagemagick.org/archive/binaries/ImageMagick-7.1.1-20-Q16-HDRI-x64-dll.exe cmd D:\soft\ImageMagick-7.1.1-Q16-HDRI\magick.exe "C:\Users\Gamer\Downloads\iCloud 照片1\iCloud 照片\IMG_3889.HEIC" IMG_3889.jpg

WebSocket: 实时通信的新维度

介绍&#xff1a; 在现代Web应用程序中&#xff0c;实时通信对于提供即时更新和交互性至关重要。传统的HTTP协议虽然适合请求-响应模式&#xff0c;但对于需要频繁数据交换的场景并不理想。而WebSocket技术的出现填补了这个空白&#xff0c;为Web开发者们带来了一种高效、实时的…

Elucidating the Design Space of Diffusion-Based Generative Models 阅读笔记

文章用一种新的设计框架统一diffusion-based model&#xff0c;并使用模块化&#xff08;modular&#xff09;的思想&#xff0c;分别从采样、训练、score network设计三个方面分析和改进diffusion-based model。 之前的工作1已经把diffusion-based model统一到SDE或者ODE框架…

10-k8s-身份认证与鉴权

文章目录 一、ServiceAccount介绍二、ServiceAccount相关的资源对象三、dashboard空间示例 一、ServiceAccount介绍 ServiceAccount&#xff08;服务账户&#xff09;概念介绍 1&#xff09;ServiceAccount是Kubernetes集群中的一种资源对象&#xff0c;用于为Pod或其他资源提供…

JavaScript基础知识14——运算符:逻辑运算符,运算符优先级

哈喽&#xff0c;大家好&#xff0c;我是雷工&#xff01; 一、逻辑运算符 1、概念&#xff1a;在程序中用来连接多个比较条件时候使用的符号。 2、应用场景&#xff1a;在程序中用来连接多个比较条件时候使用。 3、逻辑运算符符号&#xff1a; 4、代码演示逻辑运算符的使用…

手机流量卡经营商城小程序的作用是什么

流量卡成为很多用户的选择&#xff0c;同时市场中也出现了不少流量卡卖家&#xff0c;基于多种形式开展生意。然而虽然市场需求度高&#xff0c;但流量卡经营难题也不少。 流量卡客户具有高忠诚度&#xff0c;然而入驻线上第三方平台&#xff0c;客户属于平台&#xff0c;无法…

四川天蝶电子商务有限公司抖音电商服务引领行业标杆

随着电子商务的飞速发展&#xff0c;四川天蝶电子商务有限公司作为一家领先的抖音电商服务提供商&#xff0c;已经脱颖而出。本文将详细解析四川天蝶电子商务有限公司的抖音电商服务&#xff0c;让您一探究竟。 一、卓越的服务理念 四川天蝶电子商务有限公司始终坚持以客户为中…

多媒体应用设计师 第3章 多媒体信息传输技术

1.数据通信技术 1.1.多媒体通信的服务质量 多媒体服务质量(Qos)指网络服务的良好程度&#xff0c; 衡量QoS的常见指标为:吞吐量&#xff0c;差错率&#xff0c;端到端延迟&#xff0c;延迟抖动,带宽&#xff0c;丢包率&#xff0c;服务可用性等。 1.2.多媒体通信的服务质量类…

flask基础开发知识学习

之前做了一些LLM的demo&#xff0c;接口用flask写的&#xff0c;但是涉及到后端的一些业务就感觉逻辑写的很乱&#xff0c;代码变成屎山&#xff0c;于是借助官方文档和GPT迅速补了一些知识&#xff0c;总结一下一个很小的模板 于是决定边学边重构之前的代码… 文章目录 代码结…

【milkv】更新rndis驱动

问题 由于windows升级到了11&#xff0c;导致rndis驱动无法识别到。 解决 打开设备管理器&#xff0c;查看网络适配器&#xff0c;没有更新会显示黄色的图标。 右击选择更新驱动