路径规划——广度优先搜索与深度优先搜索

路径规划——广度优先搜索与深度优先搜索

https://www.hello-algo.com/chapter_graph/graph_traversal/

1.广度优先搜索 Breath-First-Search

在图论中也称为广度优先遍历,类似于树的层序遍历。

算法原理

从起始节点出发,首先访问它的邻近节点,然后依次访问这些邻近节点的邻近节点,直到所有节点都被访问到。广度优先搜索是从一个起始节点开始逐层地访问所有节点的。

广度优先搜索是一种图遍历算法,每向前走一步可能访问一批顶点,不像深度优先搜索那样有回退的情况,因此它不是一个递归的算法。为了实现逐层的访问,算法必须借助一个辅助队列,以记忆正在访问的顶点的下一层顶点。

现有如下节点图Graph,要求从A点开始搜索,搜索全部节点,将节点搜索序列作为结果输出。
在这里插入图片描述

将上图整理得下图
在这里插入图片描述

那么整个广度优先搜索的过程如下图:
在这里插入图片描述

算法实现

from collections import dequedef bfs(graph, start):# 初始化队列,并将起始节点加入队列queue = deque([start])# 初始化访问顺序列表visited = [start]while queue:# 取出队列中的当前节点current = queue.popleft()# 遍历当前节点的所有邻居节点for neighbor in graph[current]:if neighbor not in visited:  # 如果邻居节点尚未被访问# 将邻居节点加入队列queue.append(neighbor)# 记录访问顺序visited.append(neighbor)return visited# 示例图的定义
graph = {'A': ['B', 'C'],'B': ['A', 'D', 'E'],'C': ['A', 'F'],'D': ['B'],'E': ['B', 'F'],'F': ['C', 'E']
}# 使用BFS算法
start_node = 'A'
visited = bfs(graph, start_node)
print(f"Visit order: {visited}")

寻找在上图中A->E的最短路径:

from collections import dequedef bfs(graph, start, goal):# 初始化队列,并将起始节点加入队列queue = deque([start])# 初始化访问顺序列表visited = [start]# 初始化父节点集合previous = {start: None}while queue:# 取出队列中的当前节点current = queue.popleft()if current == goal:break# 遍历当前节点的所有邻居节点for neighbor in graph[current]:if neighbor not in visited:  # 如果邻居节点尚未被访问# 将邻居节点加入队列queue.append(neighbor)# 记录访问顺序visited.append(neighbor)# 将当前节点保存为邻节点的父节点previous[neighbor] = currentpath = []current = goal# Find the full path by backtrackingwhile current is not None:path.append(current)current = previous.get(current)path = path[::-1]distance = len(path)-1return path,distance# 示例图的定义
graph = {'A': ['B', 'C'],'B': ['A', 'D', 'E'],'C': ['A', 'F'],'D': ['B'],'E': ['B', 'F'],'F': ['C', 'E']
}# 使用BFS算法
start = 'A'
goal = 'E'
path,distance = bfs(graph, start, goal)
print("Distance: ",distance)
print(f"Short path: {path}")

输出结果:
在这里插入图片描述

利用BFS算法寻找栅格地图中两点之间的最短路径的代码实现如下:


from collections import deque
import numpy as npclass BFS:def __init__(self, grid, board_size, start, goal):self.grid = gridself.board_size = board_sizeself.start = startself.goal = goaldef plan(self):"""Use BFS algorithm to plan path in grid map.Since the cost between every two neighbouring nodes is 1 which is different from Dijkstra,only four directions including up, right, down, left are allowed"""visited = set() # Used to mark nodes that are visitedself.searched = [] # Used to record nodes that are searchedprevious_nodes = {self.start: None}que = deque([self.start])visited.add(self.start)while que:# Select the node closest to the start nodecurrent_node = que.popleft()# Append the current node into searched nodesself.searched.append(current_node)# Break when the current node is the goalif current_node == self.goal:break# Find the neighbors of the current node and determine in turn if they have already been visitedneighbors = self.get_neighbors(current_node)for neighbor in neighbors:# If the current node has been visited, skip itif neighbor in visited:continueprevious_nodes[neighbor] = current_nodeque.append(neighbor)visited.add(neighbor) # mark the neighbor is visitedself.path = []current_node = self.goal# Find the full path by backtrackingwhile current_node is not None:self.path.append(current_node)current_node = previous_nodes.get(current_node)self.path = self.path[::-1]return len(self.path)-1def get_neighbors(self, node):neighbors = []next_directions = [(1,0),(0,-1),(-1,0),(0,1)]for next_d in next_directions:neighbor = (node[0] + next_d[0], node[1] + next_d[1])if self.board_size <= neighbor[0] < len(self.grid)-self.board_size and self.board_size <= neighbor[1] < len(self.grid[0])-self.board_size:if self.grid[neighbor[0]][neighbor[1]] == 0:neighbors.append(neighbor)return neighbors

在这里插入图片描述

2.深度优先搜索 Depth-First-Search

在树和图论的数据结构中也称为深度优先遍历。

算法原理

从起始节点出发,沿着一个分支深入到尽可能深的节点,然后回溯并继续访问其他分支。这种"走到尽头再返回"的算法范式通常是基于递归来实现的。

同样以上述例子为例,整个深度优先搜索的过程如下:

在这里插入图片描述

算法实现

from collections import dequedef dfs(graph, current_node, visited):visited.append(current_node)# 遍历当前节点的所有邻居节点for neighbor in graph[current_node]:if neighbor in visited:  # 如果邻居节点已被访问则跳过continuedfs(graph, neighbor, visited)return visited# 示例图的定义
graph = {'A': ['B', 'C'],'B': ['A', 'D', 'E'],'C': ['A', 'F'],'D': ['B'],'E': ['B', 'F'],'F': ['C', 'E']
}# 使用DFS算法
start_node = 'A'
visited = dfs(graph, start_node, [])
print(f"Visit order: {visited}")

寻找在上图中A->E的最短路径:

from collections import dequedef dfs(graph, current_node, goal, path, shortest_path, distance):path.append(current_node)if current_node == goal:if len(path)-1<distance:shortest_path[:] = pathdistance = len(shortest_path)-1path.pop()return shortest_path, distance# 遍历当前节点的所有邻居节点for neighbor in graph[current_node]:if neighbor in path:  # 如果邻居节点已被访问则跳过continueshortest_path, distance = dfs(graph, neighbor, goal, path, shortest_path, distance)path.pop()return shortest_path, distance# 示例图的定义
graph = {'A': ['B', 'C'],'B': ['A', 'D', 'E'],'C': ['A', 'F'],'D': ['B'],'E': ['B', 'F'],'F': ['C', 'E']
}# 使用DFS算法
start_node = 'A'
goal = 'F'
path = []
distance = float('inf')
shortest_path, distance = dfs(graph, start_node, goal, path, [], distance)
print("Distance: ",distance)
print(f"Short path: {shortest_path}")

输出结果:

在这里插入图片描述

虽然DFS可以找到最短路径,但是需要找到所有的路径之后才能知道最短路径,所有非常耗时,例如在上述BFS中的栅格地图中寻找起点到终点的最短路径是非常困难的,尽管也可以找到最短路径但是非常耗时,所以一般不会使用DFS寻找最短路径。

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

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

相关文章

Typora2024最新版破解方法(亲测可用)

此方法非常简单&#xff0c;无需安装dll补丁&#xff0c;无需修改注册表&#xff0c;无需使用老版本。仅需修改部分文件内容即可 方法步骤 步骤一 下载并安装Typora 安装Typora 打开官网 下载并安装最新版即可 点击访问Typora官网 https://typoraio.cn/ 步骤二 修改文件 …

C#编写多导联扫描式的波形图Demo

本代码调用ZedGraph绘图框架&#xff0c;自己先安装好ZedGraph环境&#xff0c;然后拖一个zedGraphControl控件就行了&#xff0c;直接黏贴下面代码 基本代码显示 using System; using System.Windows.Forms; using ZedGraph; using System.Timers;namespace ECGPlot {public…

Bugku-ctf-web

Simple_SSTI_1 1.启动场景&#xff0c;http://114.67.175.224:12592 2.页面提示传入参数flag&#xff0c;F12查看源码得到第二个提示 3.SECRET_KEY(秘钥)是Flask中重要的一个配置值&#xff0c;在这题&#xff0c;构造语句查看它&#xff0c;得到flag&#xff0c;也可以构造?…

python+selenium+unittest自动化测试框架

前言 关于自动化测试的介绍&#xff0c;网上已有很多资料&#xff0c;这里不再赘述&#xff0c;UI自动化测试是自动化测试的一种&#xff0c;也是测试金字塔最上面的一层&#xff0c;selenium是应用于web的自动化测试工具&#xff0c;支持多平台、多浏览器、多语言来实现自动化…

AGV系统设计解析:布局-车体-对接-数量计算-路径规划

AGV AGV是实现柔性制造、装配及自动化物流的关键设备之一&#xff0c;近几年来&#xff0c;随着各国智能制造政策的不断实施&#xff0c;促进了AGV产业的快速发展。 目前&#xff0c;AGV系统广泛应用于各个行业之中&#xff0c;比如物流行业、新能源行业、汽车行业、制药行业等…

Python爬虫入门02:Fiddler下载使用教程

文章目录 手机抓包全攻略&#xff1a;Fiddler 工具深度解析引言Fiddler 工具简介为什么选择 Fiddler&#xff1f; 安装与配置 Fiddler步骤一&#xff1a;下载与安装步骤二&#xff1a;配置浏览器代理步骤三&#xff1a;安装 HTTPS 证书 配置手机以使用 Fiddler步骤一&#xff1…

堆的创建和说明

文章目录 目录 文章目录 前言 小堆&#xff1a; 大堆&#xff1a; 二、使用步骤 1.创建二叉树 2.修改为堆 3.向上调整 结果实现 总结 前言 我们已经知道了二叉树的样子&#xff0c;但是一般的二叉树是没有什么意义的&#xff0c;所以我们会使用一些特殊的二叉树来进行实现&a…

码农职场:一本专为IT行业求职者量身定制的指南

目录 写在前面 推荐图书 推荐理由 写在后面 写在前面 本期博主给大家推荐一本专为IT行业求职者量身定制的指南&#xff1a;《码农职场》。 推荐图书 https://item.jd.com/14716160.html 内容简介 这是一本专为广大IT 行业求职者量身定制的指南&#xff0c;提供了从职前…

Netty 必知必会(四)—— Channel-Pipeline 责任链

一、责任链模式 适用场景: 对于一个请求来说&#xff0c;如果每个对象都有机会处理它&#xff0c;而且不明确到底是哪个对象会处理请求时&#xff0c;我们可以考虑使用责任链模式实现它&#xff0c;让请求从链的头部往后移动&#xff0c;直到链上的一个节点成功处理了它为止 …

python爬虫初识

一、什么互联网 互联网&#xff08;Internet&#xff09;是全球范围内最大的计算机网络&#xff0c;它将数以百万计的私人、公共、学术、商业和政府网络通过一系列标准通信协议&#xff08;如TCP/IP&#xff09;连接起来形成的一个庞大的国际网络。 互联网的起源可以追溯到196…

Java 后端已经过时的技术,也是我逝去的青春

最近这段时间收到了一些读者的私信&#xff0c;问我某个技术要不要学&#xff0c;还有一些的同学竟然对 Java 图形化很感兴趣&#xff0c;还想找这方面的工作。 我接触 Java 已近 10多年了&#xff0c;见证了许多 Java 技术变迁&#xff0c;包括&#xff1a; JavaEE 框架&…

常见的应急救援设备有哪些_鼎跃安全

在我们的生活中&#xff0c;应急事件的发生常常是突如其来的&#xff0c;它们对人民的生命财产安全构成重大威胁&#xff0c;同时也对社会稳定提出严峻挑战。在这样的紧急情况下&#xff0c;迅速开展有效的救援工作显得尤为重要。而在整个救援过程中&#xff0c;应急设备的使用…

1-4章节复习总结

1-4章节总结 章节重点回顾-第一章-中央处理单元练习题 章节重点回顾-第一章-进制章节重点回顾-第一章-校验码奇偶校验码CRC循环冗余校验码海明码练习题 多草节重点回顾-第一草-计算机体系结构分类章节重点回顾-第一章-计算机指令练习题 章节重点回顾-第一章-指令流水线练习题 章…

canvas绘制表格

canvas绘制表格 最近在为公司产品做技术预研&#xff0c;经理让用canvas做一个表格&#xff0c;于是就有了这篇博客。 我们的数据是后端通过MQTT推送过来的 我在代码中也直接使用了 具体MQTT的实现代码&#xff0c;可见博客 在vue使用MQTT 在这里为了方便实用我直接封装成组件…

POI 快速入门 Excel导入导出

Excel导入导出 1 什么是POI POI简介&#xff08;Apache POI&#xff09;&#xff0c;Apache POI是Apache软件基金会的开放源码函式库&#xff0c;POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 Apache POI官网http://poi.apache.org/ HSSF &#xff0d; 提…

攻防世界之《这个按钮做什么》题解

下载解压后&#xff0c;发现只有一个文件。 放入exeinfope软件里看看 根据activity猜测可能是安卓软件&#xff0c;修改文件后缀为.apk 然后用模拟器打开这个软件并会自动安装。 打开软件界面如下&#xff1a; 看得出来只有一个密码输入框&#xff0c;应该找到对应的密码就会…

每日一面系列之美团面试拷打:ConcurrentHashMap 为何不能插入 null?HashMap 为何可以

ConcurrentHashMap 为什么 key 和 value 不能为 null&#xff1f; ConcurrentHashMap 的 key 和 value 不能为 null 主要是为了避免二义性。null 是一个特殊的值&#xff0c;表示没有对象或没有引用。如果你用 null 作为键&#xff0c;那么你就无法区分这个键是否存在于 Concu…

仓颉语言 -- 网络编程

使用新版本 &#xff08;2024-07-19 16:10发布的&#xff09; 1、网络编程概述 网络通信是两个设备通过计算机网络进行数据交换的过程。通过编写软件达成网络通信的行为即为网络编程。 仓颉为开发者提供了基础的网络编程功能&#xff0c;在仓颉标准库中&#xff0c;用户可使用…

资源|Python入门必看书籍,适合零基础小白,附PDF

小编为初学Python的朋友们汇总了7本零基础入门书籍&#xff0c;包括Python三剑客等&#xff0c;都是在编程届多年畅销的书籍&#xff0c;也是众多从业者的选择&#xff0c;全文详细介绍了书籍主要内容&#xff0c;有需要的宝子根据自身情况自取 需要书籍PDF的宝子评论区留言哦 …

IIS解析漏洞~IIS6.X漏洞分析

类型代码量作用一句话木马代码量极少配合webshell管理工具使用小马代码量比小马多大马代码量最多功能比较完善&#xff08;执行命令&#xff0c;文件操作等&#xff09;图片马里面传有一句话木马 文件解析漏洞是由于中间件错误的将特殊格式的文件解析成可执行网页文件(脚本)&am…