算法之迷宫解法

news2024/11/27 6:17:47

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 一、迷宫是什么?
  • 二、迷宫的生成
    • 迷宫的数据结构
      • 二维数组
    • Prim算法生成地图
      • 什么是Prim算法?
      • 使用Prim对迷宫生成的实现
  • 三、迷宫的解法
    • 深度优先遍历(DFS)


前言

前几天刷抖音刷到一个迷宫解法,觉得很有意思,想把迷宫解法好好玩玩分析一下,发现里面内容和学问多着呢,是一个非常有意思的主题。除了有如何找到迷宫从入口到出口的路径的玩法,还有如何生成一个迷宫的玩法。玩迷宫之前,首先我们要弄清楚一个问题,迷宫是什么?只有当我们弄清楚了迷宫的定义,才能玩好迷宫。


一、迷宫是什么?

迷宫是一个由格子或单元组成的矩形网格,其中包含一些可行走的路径和墙壁。迷宫通常具有一个入口和一个或多个出口,玩家的目标是从入口找到通向出口的路径。迷宫中的路径应该是连通的,所有的网格都应该是可达的,并且不应该包含环路。

二、迷宫的生成

根据上面迷宫的定义,大概就能明白什么是迷宫了。现在问题来了,应该如何生成一个随机的迷宫呢。当然生成之前,更应该解决的问题是迷宫的数据应该如何保存呢?用什么数据结构呢?

迷宫的数据结构

能很快想到的就是二维数组。还有什么数据结构呢?根据迷宫的定义可以想到,用也可以表示一个迷宫。

二维数组

二维数组是一种非常直观的方式来表示迷宫。每个元素可以代表迷宫的一个单元格,值可以表示该单元格的状态,例如,是否是墙壁,是否已经被访问过等。例如,我们可以使用0表示空白单元格,1表示墙壁。

如果是使用二维数组,又有一个问题,如果是一个 3 ∗ 3 3*3 33的迷宫
在这里插入图片描述
也就是这样一个迷宫,那应该使用多大的二维数组呢?int[n][n],n应该是多少呢?也是3吗?如果不清楚,那我再将这个迷宫地图转换成块状的地图。
在这里插入图片描述
这两个是相同的地图,这时候是不是更明朗了?如果一个 3 ∗ 3 3*3 33的迷宫地图,应该使用二位数组int[7][7],也就是一个 n ∗ n n*n nn的迷宫地图,要使用int[n*2+1][n*2+1]的二维数组。而且如果迷宫地图每个网格都是可达的话,也就是二维数组初始状态就有很多数组为0的数。那二维数组初始时候应该是什么样呢?我写了一个生成地图的算法,用的是Prim算法。
这是我用javaFX做的一个展示效果,迷宫地图是 10 ∗ 10 10*10 1010
请添加图片描述
这时候是不是就很清晰了,二维数组初始的状态,而生成迷宫地图要做的就是打破单元格之间的墙壁。让每个房间都变成联通的。

迷宫也可以被视为一个,其中每个单元格是一个节点,如果两个单元格之间没有墙壁,那么这两个节点之间就存在一条边。这种表示方式对于使用图算法(如深度优先搜索广度优先搜索)来解决迷宫问题非常有用。(还没实现,以后实现了再补充。。。)

Prim算法生成地图

什么是Prim算法?

Prim算法是一种用于生成最小生成树的贪心算法。最小生成树是一个图中的一个子图,它包含了图中的所有顶点,并且是所有可能的生成树中总权值最小的。生成树是一个无环的连通子图。

Prim算法的基本步骤如下:

  1. 初始化:从图的所有顶点中任意选择一个顶点作为起始点。
  2. 选择边:在已经访问过的顶点(已经在生成树中的顶点)的所有邻边中,选择一条权值最小的边,该边连接的另一顶点未被访问过。
  3. 添加顶点:将这条边的另一顶点加入到已访问的顶点集合中(即加入到生成树中)。
  4. 重复步骤:重复步骤2和3,直到所有的顶点都被访问过。

这个过程会生成一个最小生成树,其中包含了原图中的所有顶点,并且所有边的总权值最小。

Step 1: Initialize
Step 2: Select Edge
Step 3: Add Vertex
Step 4: Repeat Steps

使用Prim对迷宫生成的实现

对于迷宫地图的生成来说,迷宫初始化为0(迷宫的可达方格)的值就是图的顶点,而地图需要打破的方格之间的墙壁,也就是边。生成一个迷宫地图。我们要做的就是选择可以打破的边,直到所有方格都被访问。

    public int[][] generateMaze(int[] start) {
        initMaze();
        candidates.clear();
        //存储候选者<候选边,候选点>
        candidates.addAll(getCandidates(start));
        while (candidates.size() > 0) {
            int index = new Random().nextInt(candidates.size());
            Candidate current = candidates.get(index);
            if (!isCandidate(current)) {
                candidates.remove(current);
                continue;
            }
            maze[current.verge[0]][current.verge[1]] = 0;
            candidates.remove(index);
            List<Candidate> newCandidates = getCandidates(current.node);
            candidates.addAll(newCandidates);
        }
        return maze;
    }

我这里使用的是Prim算法的变式,流程如下:

  1. 选择一个方格作为起始点。
  2. 将该方格所有邻边添加到候选队列。
  3. 从候选队列中随机访问一个边。
  4. 判断这个边是否可以被打破。
  5. 如果可以,访问新的未访问过的方格,并将这个方格的所有邻边添加到候选队列。
  6. 如果不可以,从候选队列中移除这个候选者。
  7. 重复步骤3到6,直到所有的顶点都被访问过。
可以
不可以
步骤1: 选择一个方格作为起始点
步骤2: 将该方格所有邻边添加到候选队列
步骤3: 从候选队列中随机访问一个边
步骤4: 判断这个边是否可以被打破
步骤5: 访问新的未访问过的方格并将这个方格的所有邻边添加到候选队列
步骤6: 从候选队列中移除这个候选者

三、迷宫的解法

深度优先遍历(DFS)

这里我使用了栈的数据结构,每次访问一个新的方格的时候,将该方格出栈,将新的可以访问的方格入栈,如果是遇到交叉路口,就把交叉路口的所有方向方格都入栈。当遇到死胡同的时候,就可以返回到上一个交叉路口,继续重复上面步骤,直到找到终点。
示意图:
在这里插入图片描述


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鲸落送书第一期清华出版社系列丛书

1.《Rust项目开发实战》 《Rust项目开发实战》详细阐述了与Rust语言开发相关的基本解决方案&#xff0c;主要包括Rust语言简介、存储和检索数据、创建REST Web服务、创建完整的服务器端Web应用程序、利用Yew创建客户端WebAssembly应用程序、利用quicksilver创建WebAssembly游戏…

【Logback技术专题】「入门到精通系列教程」深入探索Logback日志框架的原理分析和开发实战技术指南(上篇)

深入探索Logback日志框架的原理分析和开发实战指南系列 Logback日志框架Logback基本模块logback-corelogback-classiclogback-accessLogback的核心类LoggerAppenderLayoutLayout和Appender filterlogback模块和核心所属关系 Logbackj日志级别日志输出级别日志级别介绍 Logback的…

MM32F3273G8P火龙果开发板MindSDK开发教程19 - littlefs文件系统的移植

MM32F3273G8P火龙果开发板MindSDK开发教程19 - littlefs文件系统的移植 1、littlefs简介 LittleFS 由ARM官方发布&#xff0c;ARM mbedOS的官方推荐文件系统&#xff0c;具有轻量级&#xff0c;掉电安全的特性。主要用在微控制器和flash上&#xff0c;特点如下&#xff1a; 掉…

java中的多线程、同步代码块、同步方法、锁

一、java中实现多线程的三种方式 &#xff08;1&#xff09;继承Thread类的方式进行实现&#xff1b; &#xff08;2&#xff09;实现Runnable接口的方式进行实现&#xff1b; &#xff08;3&#xff09;利用Callable接口和Future接口方式实现。 1.继承Thread类的方式进行实现 …

【性能优化】性能优化

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录 性能优化运行效率![在这里插入图片描述](https://img-blog.csdnimg.cn/557680b0ca51484c9c2c6c2…

金升阳|三极管的开关速度如何提高?

​三极管是一种常见的电子器件&#xff0c;广泛应用于电路中。它的开关速度是指从关断到导通或从导通到关断的转换速度。提高三极管的开关速度可以提高电路的响应速度&#xff0c;从而提高系统的性能。本文将介绍一些常见的方法来提高三极管的开关速度。 一、选择合适的三极管 …

华为组播实验pim-dm

组播源配置&#xff1a; R1: [r1]dis current-configuration [V200R003C00] sysname r1 snmp-agent local-engineid 800007DB03000000000000 snmp-agent clock timezone China-Standard-Time minus 08:00:00 portal local-server load flash:/portalpage.zip drop illegal-mac…

2023年软件测试有前途吗?技术变革,测试人的进阶发展路线...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 软件测试行业是否…

瑞吉项目优化

Redis缓存菜品 动态构造key。客户端传来的分类id作为key。从redis中获取缓存的数据。根据分类Id&#xff0c;使用redisTemplate.opsForValue().get 方法获取缓存的数据。如果缓存数据存在&#xff0c;直接返回&#xff0c;无需访问数据库。如果不存在&#xff0c;需要查询数据…

Redis从入门到精通【高阶篇】之底层数据结构整数集(IntSet)详解

文章目录 0.前言1.IntSet基本详解1.1 整数集的压缩算法原理1.2 整数集编码方式选择原理1.2.1 判断逻辑1.2.2 举例说明 2. 源码解析2.1. intsetNew2.2. intsetAdd2.3. intsetRemove2.4. intsetFind2.5. intsetUpgradeAndAdd2.6 收获 3.总结4.思考题5. Redis从入门到精通系列文章…

【MySQL 数据库的命令操作】

目录 一、数据库的基本概念二、数据库的发展三、主流的数据库介绍五、关系数据库1、数据库的解释2、数据库的管理3、常用的数据类型4、常见的数据库结构5、SQL语句 四、MySQL 安装方法1、安装Mysql环境依赖包2、创建运行用户3、编译安装4.创建mysql用户5.修改mysql 配置文件6、…

手动将第三方资源加IOC容器中

说明&#xff1a;在SpringBoot中&#xff0c;我们可以通过在各层类上加注解&#xff08;Mapper、Service等&#xff09;声明Bean对象&#xff0c;在需要使用时&#xff0c;可直接使用AutoWirted注解自动装配。但如果是使用第三方依赖中的对象&#xff0c;因为源码不能修改&…

04 类图

类图 定义 类图显示了类(及其接口)、类的内部结构以及与其他类的联系&#xff0c;是面向对象分析和设计所得到的最重要的模型。 作用&#xff1a;可视化地表达系统的静态结构模型 类之间的几种关系&#xff1a;泛化&#xff08;Generalization&#xff09;、实现&#xff08;…

多元回归预测 | Matlab海洋捕食者算法(MPA)优化核极限学习机回归预测,MPA-KELM回归预测,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab海洋捕食者算法(MPA)优化核极限学习机回归预测,MPA-KELM回归预测,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %% …

Jenkins部署及使用

Jenkins 1.定义 1.Jenkins是一款开源CI/CD软件&#xff0c;用于自动化各种任务&#xff0c;包括构建、测试和部署软件 1.CI/CD 1.CI&#xff1a;持续集成(Continuous Integration) 1.协同开发是目前主流的开发方式&#xff0c;一般由多位开发人员同时处理同一个应用的不同模块…

vue07---elementui使用/

elementui使用 cnpm isntall -S element-ui2.9 <template><div><h1>按钮的使用</h1><el-button-group><el-button type"primary" icon"el-icon-edit"></el-button><el-button type"primary" icon&…

《实战AI低代码》生成式AI和低代码开发的融合对组织效率的影响

目录 1. 自动化重复任务: 2. 智能流程优化: 3. 增强公民开发者: 4. 快速原型设计和实验: 5. 智能应用程序维护和更新: 随着科技的不断发展,生成式人工智能(AI)和低代码软件的融合已经成为了一个热门话题。这两种技术的结合可以加速创新并改变组织运作的方式。在本…

性能测试-平均事务响应时间ART分析解析,要卷就卷成最强的...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 业务背景&#xf…

5.基于图神经网络的点云分类

目录 一、数据处理二、点云生成三、PointNet阶段1&#xff1a;通过动态图生成进行分组阶段2&#xff1a;邻居聚合 四、网络架构五、训练程序 在本教程中&#xff0c;您将学习使用图神经网络进行点云分类的基本工具。在这里&#xff0c;我们得到了一个对象或点集的数据集&#x…

北京大学研发基于机器学习的多能干细胞分化系统,高效、稳定制备功能性细胞

内容一览&#xff1a;20 世纪以来&#xff0c;干细胞与再生医学技术一直是国际生物医学领域的热点前沿之一。现如今&#xff0c;研究人员已开始探索将干细胞转变为特定类型细胞。然而&#xff0c;这一过程中干细胞会出现不规则生长或自发分化为不同类型细胞的情况&#xff0c;因…