数据结构与算法-DFS+BFS篇(迷宫问题)

简介: 数据结构与算法-DFS+BFS篇(迷宫问题)

简介:

       1.DFS(深度优先搜索)算法是一种用于遍历或搜索树或图数据结构的算法。该算法从起始顶点开始,沿着一条路径尽可能深入地访问顶点,直到该路径上的所有顶点都被访问过为止。然后回溯到前一个顶点,继续探索其他路径,直到所有可能的路径都被探索完毕。(不撞南墙不回头)

  2.BFS(广度优先搜索)算法是一种用于遍历或搜索树或图数据结构的算法。与DFS不同,BFS从起始顶点开始,先访问起始顶点的所有相邻顶点,然后再依次访问这些相邻顶点的相邻顶点,依此类推,直到所有顶点都被访问过为止。

实现:

       1.DFS算法通常使用递归或栈来实现。在递归实现中,每次访问一个顶点时,递归地访问其相邻的未访问过的顶点。在栈实现中,将起始顶点入栈,然后循环弹出栈顶顶点并访问其相邻的未访问过的顶点,将这些相邻顶点入栈,直到栈为空。

   2.BFS算法通常使用队列来实现。将起始顶点入队,然后循环从队列中取出顶点并访问其相邻的未访问过的顶点,将这些相邻顶点入队,直到队列为空。

实例:

   谈起DFS和BFS,在算法篇中最出名的就是迷宫问题了吧。给定一个由数字0和1组成的矩阵,我们将其称之为迷宫,数字1代表墙壁,0则代表着可以正常走的路。要求我们找到一条可以从起点到达终点的路线并将其输出。

这时候就需要引入我们的搜索算法DFS和BFS,这两种算法对不同的题目要求有不同的优势。比如DFS可以更加迅速的找到出路,找到出路即停止寻找。但是不能保证这条路是最优路线(即不能保证路程最短);而BFS可以遍历所有可能的路线并找到其中的 最优解(即路程最短的路线),但是BFS需要遍历所有可能的路线,而且需要更多的空间去储存队列,所以其复杂度会略高于DFS。下面直接上迷宫:

maze=[
    [1,1,1,1,1,1,1,1,1,1],
    [1,0,0,1,0,0,0,1,0,1],
    [1,0,0,1,0,0,0,1,0,1],
    [1,0,0,0,0,1,1,0,0,1],
    [1,0,1,1,1,0,0,0,0,1],
    [1,0,0,0,1,0,0,0,0,1],
    [1,0,1,0,0,0,1,0,0,1],
    [1,0,1,1,1,0,1,1,0,1],
    [1,1,0,0,0,0,0,0,0,1],
    [1,1,1,1,1,1,1,1,1,1]
]
# 起点为(1,1);终点为(8,8)
dirs=[
    lambda x,y:(x+1,y), #往右走
    lambda x,y:(x-1,y), #往左走
    lambda x,y:(x,y+1), #往下走
    lambda x,y:(x,y-1)  #往上走
]

如果我们仅仅需要找到行得通的路线的话,我们可以使用DFS来解决,下面附上DFS的解题代码:

# DFS 解法
def maze_path(x1,y1,x2,y2):
    stick=[(x1,y1)]
    while stick:
        curcode=stick[-1]   # 后进先出
        if curcode[0]==x2 and curcode[1]==y2:  # 到达终点的判断
            for j in stick:
                print(j)
            print(len(stick))  # 一共走的步数
            return True
        for dir in dirs:   # 四条路遍历
            nextcode=dir(curcode[0],curcode[1])  # 对x,y进行改变的一个过程
            if maze[nextcode[0]][nextcode[1]] == 0: # 能走
                stick.append((nextcode))
                maze[nextcode[0]][nextcode[1]]=2 # 代表走过了
                break  # 有一条路能走时,就立即break,保证只走一条路,一条路走到黑。这就是DFS的魅力!
        else:
            maze[nextcode[0]][nextcode[1]] = 2  #四条路都不能走
            stick.pop()   # 删掉这个节点,退一步,继续找出路。
    else:
        print('没有路')
        return False
maze_path(1,1,8,8)

然而,在实际问题中,我们往往需要找到最优解,而DFS则无法实现此功能,此时我们运用BFS广度优先来解决。下面附上BFS解题代码:

# BFS 解法
from collections import deque
def print_r(path):   # 输出函数,定义了输出的格式
    curnode=path[-1]
    realpath=[]
    while curnode[2]!=-1:
        realpath.append(curnode[0:2])
        curnode= path[curnode[2]]
 
    realpath.append(curnode[0:2]) # 起点
    realpath.reverse()
    for i in realpath:
        print(i)
 
def maze_path_queue(x1,y1,x2,y2):
    queue = deque()  # 运用了队列
    queue.append((x1,y1,-1))  # 最大的不同就是 这里多了一个下标 用于储存子父关系 方便后续的输出
    path=[]
    while queue:
        curnode=queue.popleft() # 先进先出
        path.append(curnode)
        if curnode[0]==x2 and curnode[1]==y2:  # 到达终点的判断
            # 终点
            print_r(path)  # 调用输出函数
            return True
        for dir in dirs:
            nextnode = dir(curnode[0],curnode[1])   # 调用dir中的lambda函数,对x,y进行修改
            if maze[nextnode[0]][nextnode[1]] ==0: # 表示能走
                queue.append((nextnode[0],nextnode[1],len(path)-1))
                maze[nextnode[0]][nextnode[1]]=2 # 标记为已经走过  这里没有用break 因为是广度优先 所有情况都要遍历一遍 不过这里的子父关系很明确
    else:
        print('没有路')
        return False
maze_path_queue(1,1,8,8)

比较:

       两者相比较,不难看出BFS要略比DFS复杂一些,在BFS中我们引入了队列并额外定义了一个输出函数print_r,以满足我们的格式要求并计算出最短路径的步数。

说明:

       迷宫问题是数据结构与算法DFS+BFS篇中比较典型且综合的题目,通过此类问题可以提高我们的代码实现能力,帮助我们掌握DFS以及BFS算法基础。对于稍有难度且重要的知识点我们要多多回顾并总结。

温故而知新,可以为师矣!

目录
相关文章
|
4月前
|
机器学习/深度学习 算法 C++
【DFS/回溯算法】2016年蓝桥杯真题之路径之谜详解
题目要求根据城堡北墙和西墙箭靶上的箭数,推断骑士从西北角到东南角的唯一路径。每步移动时向正北和正西各射一箭,同一格不重复经过。通过DFS回溯模拟“拔箭”过程,验证路径合法性。已知箭数约束路径唯一,最终按编号输出行走顺序。
|
5月前
|
机器学习/深度学习 算法 机器人
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
330 3
|
机器学习/深度学习 算法
算法系列之搜索算法-深度优先搜索DFS
深度优先搜索和广度优先搜索一样,都是对图进行搜索的算法,目的也都是从起点开始搜索,直到到达顶点。深度优先搜索会沿着一条路径不断的往下搜索,直到不能够在继续为止,然后在折返,开始搜索下一条候补路径。
922 62
算法系列之搜索算法-深度优先搜索DFS
|
8月前
|
机器学习/深度学习 算法 数据可视化
基于Qlearning强化学习的机器人迷宫路线搜索算法matlab仿真
本内容展示了基于Q-learning算法的机器人迷宫路径搜索仿真及其实现过程。通过Matlab2022a进行仿真,结果以图形形式呈现,无水印(附图1-4)。算法理论部分介绍了Q-learning的核心概念,包括智能体、环境、状态、动作和奖励,以及Q表的构建与更新方法。具体实现中,将迷宫抽象为二维网格世界,定义起点和终点,利用Q-learning训练机器人找到最优路径。核心程序代码实现了多轮训练、累计奖励值与Q值的可视化,并展示了机器人从起点到终点的路径规划过程。
420 0
|
10月前
|
算法 数据可视化 Python
Python中利用遗传算法探索迷宫出路
本文探讨了如何利用Python和遗传算法解决迷宫问题。迷宫建模通过二维数组实现,0表示通路,1为墙壁,'S'和'E'分别代表起点与终点。遗传算法的核心包括个体编码(路径方向序列)、适应度函数(评估路径有效性)、选择、交叉和变异操作。通过迭代优化,算法逐步生成更优路径,最终找到从起点到终点的最佳解决方案。文末还展示了结果可视化方法及遗传算法的应用前景。
251 5
|
存储 算法
算法系列之搜索算法-广度优先搜索BFS
广度优先搜索(BFS)是一种非常强大的算法,特别适用于解决最短路径、层次遍历和连通性问题。在面试中,掌握BFS的基本实现和应用场景,能够帮助你高效解决许多与图或树相关的问题。
1195 1
算法系列之搜索算法-广度优先搜索BFS
|
算法 编译器 C++
【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
|
存储 人工智能 算法
【深度优先搜索篇】走迷宫的魔法:算法如何破解迷宫的神秘密码
【深度优先搜索篇】走迷宫的魔法:算法如何破解迷宫的神秘密码
|
算法
数据结构之卫星通信网络(BFS)
本文介绍了卫星通信网络及其重要性,并探讨了广度优先搜索(BFS)算法在其中的应用。卫星通信网络通过在轨卫星提供全球覆盖的通信服务,尤其在偏远地区和紧急救援中发挥关键作用。BFS算法用于网络拓扑分析、路径规划和故障排除,确保通信网络的高效运行。文章还包括BFS算法的工作原理、特点、优缺点及其实现代码示例。
454 1
|
算法 数据中心
数据结构之数据中心网络路由(BFS)
本文介绍了数据中心网络路由中使用广度优先搜索(BFS)算法的重要性及其应用。随着数据中心从集中式大型机系统发展到分布式架构,高效的数据路由成为确保低延迟、高吞吐量和网络可靠性的关键。BFS通过系统地探索网络层次,从源节点开始向外遍历,确保发现最短路径,特别适合于数据中心网络环境。文中还提供了BFS算法的具体实现代码,展示了如何在数据中心网络中应用该算法来查找节点间的最短路径,并讨论了BFS的优缺点。
397 0
数据结构之数据中心网络路由(BFS)

热门文章

最新文章