利用深度优先搜索算法解决老鼠吃奶酪问题(python)

简介: 利用深度优先搜索算法解决老鼠吃奶酪问题(python)

问题描述

一只老鼠位于迷宫左下角(0,0),迷宫中的数字9处有块大奶酪。0表示墙,1表示可通过路径。试给出一条可行的吃到奶酪的路径;若没有返回空。

假定迷宫是4连通的,即:老鼠只能上下左右走,不能斜着走。

算法描述

假定当前位于(i,j)处,尝试4个相邻位置,如果相邻位置不是墙,则可以通过。然后递归该过程。

代码如下:

import numpy as np
import matplotlib.pyplot as plt
# 常量
W = 4
H = 6
CHEESE = 9
# 深度优先搜索(迷宫,开始位置,路线存储变量,访问标志变量)
def search(maze, i, j, path, visit):
    # 找到奶酪,返回ture
    if maze[i][j] == CHEESE:
        print(path)
        return True
    # 邻居方向向量
    # 通过该向量,可以确定下一次从哪一个邻居开始搜索(左->右->下->上 或 上->下->右->左 等等),4个方向
    # 向量元素顺序的不同,有可能形成不同的最终路线
    i_next = [0, 0, -1, 1]
    j_next = [-1, 1, 0, 0]
    # i_next = [1, -1, 0, 0]
    # j_next = [0, 0, 1, -1]
    # i_next = [0, 0, -1, 1]
    # j_next = [1, -1, 0, 0]
    # 迷宫高度
    m = len(maze)
    # 迷宫宽度
    n = len(maze[0])
    # 4 连通,只能上下左右步进
    for k in range(4):
        # 从当前位置(i,j)偏移一位
        i_cur = i + i_next[k]
        j_cur = j + j_next[k]
        # 超出边界则搜索其他方向
        if i_cur < 0 or i_cur >= m or j_cur < 0 or j_cur >= n:
            continue
        # 新位置没有被访问过并且不是墙
        if (not visit[i_cur][j_cur]) and (maze[i_cur][j_cur] != 0):
            # 把iCur和jCur放置在路径中
            path.append((i_cur, j_cur))
            # 把iCur和jCur设置为已访问
            visit[i_cur][j_cur] = True
            # 递归搜索
            if search(maze, i_cur, j_cur, path, visit):
                return True
            # 从(iCur,jCur)找不到可行路径,把iCur和jCur弹出,然后回溯,搜索其他方向
            path.pop()
            visit[i_cur][j_cur] = False
    # 所有方向均找不到可行路径,返回False
    return False
# 绘制结果
def draw(maze, path):
    fig = plt.figure()
    plt.axis("off")
    ax = fig.add_subplot(111, aspect='equal')
    ax.set_xlim(0, W * len(maze[0]))
    ax.set_ylim(0, H * len(maze))
    # 迷宫上节点的位置坐标信息,用于绘图
    path_pos = dict()
    y = -H
    # 绘制迷宫和路线
    for r in range(len(maze)):
        row = maze[r]
        y += H
        x = -W
        for s in range(len(row)):
            x += W
            if (r, s) in path:
                print((r, s))
                path_pos[(r, s)] = (x, y)
                ax.add_patch(
                    plt.Rectangle(
                        (x, y),  # 矩形左下角
                        W,  # 长
                        H,  # 宽
                        color='green',
                    )
                )
            else:
                ax.add_patch(
                    plt.Rectangle(
                        (x, y),  # 矩形左下角
                        W,  # 长
                        H,  # 宽
                        edgecolor='black',
                        fill=False,
                        linewidth=1
                    )
                )
            # 绘制0,1标记
            ax.text(x + W / 2 - 0.5, y + H / 2 - 0.5, "{}".format(row[s]), transform=ax.transData)
    # 绘制路径方向箭头
    if len(path) > 2:
        for k in range(len(path) - 1):
            # 箭头开始坐标
            start = path_pos[path[k]]
            # 箭头结束坐标
            end = path_pos[path[k + 1]]
            plt.arrow(start[0] + W / 2 - 0.7, start[1] + W / 2 - 0.7, end[0]-start[0], end[1]-start[1], head_width=1, lw=1, length_includes_head=True)
    plt.show()
    # plt.savefig('mouse_path.png', dpi=800)
# 主算法
def main():
    # 初始化迷宫
    maze = []
    maze.append([1, 1, 0, 0, 0, 0, 0, 1])
    maze.append([1, 1, 1, 1, 1, 1, 1, 1])
    maze.append([1, 0, 0, 0, 1, 0, 0, 1])
    maze.append([1, 1, 1, 0, 1, 0, 0, 1])
    maze.append([0, 1, 0, 0, 1, 1, 1, 1])
    maze.append([0, 1, 0, 0, 0, 0, 0, 1])
    maze.append([0, 1, 0, 9, 1, 1, 1, 1])
    maze.append([0, 1, 1, 1, 0, 0, 1, 0])
    maze = np.array(maze)
    # 初始化路线
    path = [(0, 0)]
    # 初始化访问标记
    visit = np.full_like(maze, False)
    visit[0][0] = True
    # 开始搜索
    search(maze, 0, 0, path, visit)
    # 绘制结果
    draw(maze, path)
if __name__ == "__main__":
    main()

运行结果如下图所示:

算法搜索过程如下:

注意事项

代码中特别要注意的是“邻居方向向量”,通过该向量,可以确定下一次从哪一个邻居开始搜索,是按照左->右->下->上 的顺序还是按 上->下->右->左 或其他顺序对四个方向进行搜索,顺序的不同,有可能形成不同的最终路线,例如若按照 右->左->下->上 的顺序对四个方向进行搜索 ,最终得到的路线如下

本文参考了邹博老师的算法课程

笔者水平有限,若有不对的地方欢迎评论指正

相关文章
|
10天前
|
运维 监控 JavaScript
内网网管软件中基于 Node.js 的深度优先搜索算法剖析
内网网管软件在企业网络中不可或缺,涵盖设备管理、流量监控和安全防护。本文基于Node.js实现深度优先搜索(DFS)算法,解析其在网络拓扑遍历中的应用。通过DFS,可高效获取内网设备连接关系,助力故障排查与网络规划。代码示例展示了图结构的构建及DFS的具体实现,为内网管理提供技术支持。
34 11
|
10天前
|
机器学习/深度学习 算法
算法系列之搜索算法-深度优先搜索DFS
深度优先搜索和广度优先搜索一样,都是对图进行搜索的算法,目的也都是从起点开始搜索,直到到达顶点。深度优先搜索会沿着一条路径不断的往下搜索,直到不能够在继续为止,然后在折返,开始搜索下一条候补路径。
87 62
算法系列之搜索算法-深度优先搜索DFS
|
14天前
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
42 12
|
12天前
|
算法 安全 网络安全
基于 Python 的布隆过滤器算法在内网行为管理中的应用探究
在复杂多变的网络环境中,内网行为管理至关重要。本文介绍布隆过滤器(Bloom Filter),一种高效的空间节省型概率数据结构,用于判断元素是否存在于集合中。通过多个哈希函数映射到位数组,实现快速访问控制。Python代码示例展示了如何构建和使用布隆过滤器,有效提升企业内网安全性和资源管理效率。
45 9
|
20天前
|
监控 算法 安全
内网桌面监控软件深度解析:基于 Python 实现的 K-Means 算法研究
内网桌面监控软件通过实时监测员工操作,保障企业信息安全并提升效率。本文深入探讨K-Means聚类算法在该软件中的应用,解析其原理与实现。K-Means通过迭代更新簇中心,将数据划分为K个簇类,适用于行为分析、异常检测、资源优化及安全威胁识别等场景。文中提供了Python代码示例,展示如何实现K-Means算法,并模拟内网监控数据进行聚类分析。
35 10
|
10天前
|
存储 算法 量子技术
解锁文档管理系统高效检索奥秘:Python 哈希表算法探究
在数字化时代,文档管理系统犹如知识宝库,支撑各行各业高效运转。哈希表作为核心数据结构,通过哈希函数将数据映射为固定长度的哈希值,实现快速查找与定位。本文聚焦哈希表在文档管理中的应用,以Python代码示例展示其高效检索特性,并探讨哈希冲突解决策略,助力构建智能化文档管理系统。
|
11天前
|
存储 人工智能 算法
【深度优先搜索篇】走迷宫的魔法:算法如何破解迷宫的神秘密码
【深度优先搜索篇】走迷宫的魔法:算法如何破解迷宫的神秘密码
|
12天前
|
存储 算法 数据安全/隐私保护
探究办公室电脑怎么共享文件的 Python 算法
在数字化办公环境中,高效文件共享是提升工作效率的关键。本文聚焦于使用Python实现办公室电脑文件共享的算法,涵盖需求分析、基础实现及优化拓展。通过socket编程和文件流操作,实现文件传输,并探讨多线程、权限管理和文件索引等优化措施,确保文件共享的安全性和便捷性,助力现代办公协同。
|
7天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
本研究基于MATLAB 2022a,使用GRU网络对QAM调制信号进行检测。QAM是一种高效调制技术,广泛应用于现代通信系统。传统方法在复杂环境下性能下降,而GRU通过门控机制有效提取时间序列特征,实现16QAM、32QAM、64QAM、128QAM的准确检测。仿真结果显示,GRU在低SNR下表现优异,且训练速度快,参数少。核心程序包括模型预测、误检率和漏检率计算,并绘制准确率图。
80 65
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
|
12天前
|
算法
基于遗传优化算法的风力机位置布局matlab仿真
本项目基于遗传优化算法(GA)进行风力机位置布局的MATLAB仿真,旨在最大化风场发电效率。使用MATLAB2022A版本运行,核心代码通过迭代选择、交叉、变异等操作优化风力机布局。输出包括优化收敛曲线和最佳布局图。遗传算法模拟生物进化机制,通过初始化、选择、交叉、变异和精英保留等步骤,在复杂约束条件下找到最优布局方案,提升风场整体能源产出效率。

热门文章

最新文章