基于FLOOD Fill算法的迷宫路径求解方法研究

合集下载

漫水填充floodfill算法

漫水填充floodfill算法

漫水填充(Flood Fill)算法概述漫水填充(Flood Fill)算法是一种图像处理算法,在计算机图形学和计算机视觉中被广泛应用。

它用于填充图像中的连通区域,从一个种子点开始,沿着相邻的像素进行填充操作,直到达到某个停止条件为止。

该算法可以实现图像填充、颜色替换、图像分割等操作。

算法原理漫水填充算法基于深度优先搜索(DFS)或广度优先搜索(BFS)的思想来实现。

它通过遍历图像中的像素点,并对每个像素点进行区域判断,从而实现填充操作。

具体步骤如下: 1. 选择一个种子点(seed point)作为起始点。

2. 将起始点的颜色设为目标填充颜色。

3. 将起始点加入队列(对于BFS)或递归调用填充函数(对于DFS)。

4. 不断重复以下步骤直到填充操作结束: - 从队列中取出一个点(对于BFS)或递归返回一个点(对于DFS)。

- 判断该点是否满足填充条件:- 若满足条件,则将该点的颜色设为目标填充颜色,并将其相邻的未填充点加入队列(对于BFS)或递归调用填充函数(对于DFS)。

- 若不满足条件,则继续下一个点的判断。

5. 填充操作结束后,图像中的连通区域即被填充为目标颜色。

深度优先搜索(DFS)算法实现深度优先搜索(DFS)是漫水填充算法中常用的实现方式。

它通过递归调用填充函数来实现图像的填充。

代码实现下面是一个Python实现的深度优先搜索(DFS)算法的示例代码:def flood_fill_dfs(image, sr, sc, new_color):if image[sr][sc] == new_color:return imagefill_dfs(image, sr, sc, image[sr][sc], new_color)return imagedef fill_dfs(image, row, col, target_color, new_color):if row < 0 or row >= len(image) or col < 0 or col >= len(image[0]):returnif image[row][col] != target_color:returnimage[row][col] = new_colorfill_dfs(image, row + 1, col, target_color, new_color)fill_dfs(image, row - 1, col, target_color, new_color)fill_dfs(image, row, col + 1, target_color, new_color)fill_dfs(image, row, col - 1, target_color, new_color)算法分析深度优先搜索(DFS)算法的时间复杂度为O(M*N),其中M为图像的高度,N为图像的宽度。

漫水填充floodfill算法

漫水填充floodfill算法

漫水填充floodfill算法漫水填充算法(Flood Fill Algorithm)是一种用于图像处理的基本算法,它可以将一个封闭区域内的所有像素点都填充为同一种颜色。

这种算法通常用于图像编辑软件中的涂色功能,也可以用于计算机游戏中的地图填充等场景。

漫水填充算法的基本思路是从一个起始点开始,将其颜色替换为目标颜色,然后递归地将相邻的像素点也替换为目标颜色,直到所有与起始点相连的像素点都被替换为目标颜色为止。

这个过程可以使用栈或队列来实现。

在实际应用中,漫水填充算法还需要考虑一些细节问题,比如如何处理边界、如何处理不规则区域、如何处理透明度等。

下面我们来看一下漫水填充算法的具体实现。

1. 递归实现递归实现是漫水填充算法最简单的实现方式。

假设我们要将一个封闭区域内的所有像素点都填充为红色,起始点为(x,y),则可以按照以下步骤进行:1)将起始点的颜色替换为目标颜色。

2)递归地将起始点的上下左右四个相邻点也替换为目标颜色,直到所有与起始点相连的像素点都被替换为目标颜色为止。

递归实现的代码如下:void floodFill(int x, int y, int targetColor, int replaceColor) {if (x < 0 || x >= width || y < 0 || y >= height) return; // 越界检查if (image[x][y] != targetColor) return; // 颜色检查image[x][y] = replaceColor; // 替换颜色floodFill(x-1, y, targetColor, replaceColor); // 左floodFill(x+1, y, targetColor, replaceColor); // 右floodFill(x, y-1, targetColor, replaceColor); // 上floodFill(x, y+1, targetColor, replaceColor); // 下}2. 栈实现递归实现虽然简单,但是有可能会导致栈溢出的问题。

FloodFill算法详解及应用

FloodFill算法详解及应用

FloodFill算法详解及应⽤啥是 FloodFill 算法呢,最直接的⼀个应⽤就是「颜⾊填充」,就是 Windows 绘画本中那个⼩油漆桶的标志,可以把⼀块被圈起来的区域全部染⾊。

floodfill这种算法思想还在许多其他地⽅有应⽤。

⽐如说扫雷游戏,有时候你点⼀个⽅格,会⼀下⼦展开⼀⽚区域,这个展开过程,就是 FloodFill 算法实现的。

扫雷类似的,像消消乐这类游戏,相同⽅块积累到⼀定数量,就全部消除,也是 FloodFill 算法的功劳。

xiaoxiaole通过以上的⼏个例⼦,你应该对 FloodFill 算法有个概念了,现在我们要抽象问题,提取共同点。

⼀、构建框架以上⼏个例⼦,都可以抽象成⼀个⼆维矩阵(图⽚其实就是像素点矩阵),然后从某个点开始向四周扩展,直到⽆法再扩展为⽌。

矩阵,可以抽象为⼀幅「图」,这就是⼀个图的遍历问题,也就类似⼀个 N 叉树遍历的问题。

⼏⾏代码就能解决,直接上框架吧:// (x, y) 为坐标位置void fill(int x, int y) {fill(x - 1, y); // 上fill(x + 1, y); // 下fill(x, y - 1); // 左fill(x, y + 1); // 右}这个框架可以解决所有在⼆维矩阵中遍历的问题,说得⾼端⼀点,这就叫深度优先搜索(Depth First Search,简称 DFS),说得简单⼀点,这就叫四叉树遍历框架。

坐标 (x, y) 就是 root,四个⽅向就是 root 的四个⼦节点。

下⾯看⼀道 LeetCode 题⽬,其实就是让我们来实现⼀个「颜⾊填充」功能。

title根据上篇⽂章,我们讲了「树」算法设计的⼀个总路线,今天就可以⽤到:int[][] floodFill(int[][] image,int sr, int sc, int newColor) {int origColor = image[sr][sc];fill(image, sr, sc, origColor, newColor);return image;}void fill(int[][] image, int x, int y,int origColor, int newColor) {// 出界:超出边界索引if (!inArea(image, x, y)) return;// 碰壁:遇到其他颜⾊,超出 origColor 区域if (image[x][y] != origColor) return;image[x][y] = newColor;fill(image, x, y + 1, origColor, newColor);fill(image, x, y - 1, origColor, newColor);fill(image, x - 1, y, origColor, newColor);fill(image, x + 1, y, origColor, newColor);}boolean inArea(int[][] image, int x, int y) {return x >= 0 && x < image.length&& y >= 0 && y < image[0].length;}只要你能够理解这段代码,⼀定要给你⿎掌,给你 99 分,因为你对「框架思维」的掌控已经炉⽕纯青,此算法已经 cover 了 99% 的情况,仅有⼀个细节问题没有解决,就是当 origColor 和 newColor 相同时,会陷⼊⽆限递归。

UVaOJ 705 - Slash Maze 解题报告

UVaOJ 705 - Slash Maze 解题报告

bool canArrive(int x, int y, Change change) { int x_after_change = x % 2 + change.x; int y_after_change = y % 2 + change.y; if (0 <= x_after_change && x_after_change < 2 && 0 <= y_after_change && y_after_change < 2) { return false; } else if ((x_after_change < 0 || x_after_change >= 2) && (y_after_change < 0 || y_after_change >= 2)) { return false; } else { return true; } printf("\n"); }
void EnlargeAndSave(int x, int y, char ch);
bool canArrive(int x, int y, Change change); int FloodFill(int x, int y);
int main() { while (scanf("%d%d", &w, &h)) {
1
在 FloodFill 的时候,判断光线来的方向,找到下一个 FloodFill 的格子即可。
三种方法,第一种较为简单,但是要将原图长宽各扩大三倍,得到一张原图九倍大的新图。 而第二种方法,只要将原图扩大四倍,但是要判断要 FloodFill 的格子是否可以 FloodFill。 而第三种方法,较为复杂,对光线进来的四个方向都要判断反射出去的方向,可以用一个 enum 配合 const 数组来映射,好处就是不用扩大原图,时间复杂度相对前两种,常数较低。

和同事谈谈FloodFill算法

和同事谈谈FloodFill算法

和同事谈谈FloodFill算法今天忙完了公司的工作后,发现同事在做LeeCode的算法题,顿时来了兴趣,于是王子与同事一起探讨如何能做好算法题,今天在此文章中和大家分享一下。

我们今天谈论的是Flood Fill算法,那么什么是Flood Fill算法呢?为了理解什么是Flood Fill算法,我们先抛开算法本身的概念,王子给大家说一些平时工作生活中的场景。

1.画图工具的填充功能相信大家都用过Windows的画图工具,我们看下图用颜料桶给一个图形区域染色,这就是比较典型的Flood Fill 算法的应用。

2.扫雷游戏我们玩扫雷游戏的时候,当我们选中一块的时候,会向四周延展出一大片区域,那么有没有想过如果让你来实现这个算法,要怎么实现呢?这也是Flood Fill 算法的实际应用。

3.ps中的魔棒工具在我们使用魔棒工具抠图的时候,原理其实也是一样的,选中一处后,将相连的相似颜色的部分选中,只不过这里面多了相似颜色的算法。

好了,看完以上的场景,相信小伙伴们对Flood Fill 算法应该有一个概念性的认识了,那么再做这种题之前,我们先考虑一下要做出这种题的套路,也可以说是一种框架思维。

以上所有的例子都可以把它想成在一个图上进行操作,而图又可以叫做二维图形,既然是二维图形就可以给他加上坐标轴,(x,y)来代表一个像素点。

有了上边的想法后,继续思考,其实解决算法无外乎就是递归、遍历。

而这个问题就可以想象成一个4叉树的遍历问题,所以解题框架如下:// (x, y) 为坐标位置void fill(int x, int y) {fill(x - 1, y); // 左fill(x + 1, y); // 右fill(x, y - 1); // 下fill(x, y + 1); // 上}这个框架其实很容易理解,对于四叉树结构,或者说二维矩阵的结构,这个框架基本都可以解决,从选中的像素点开始,向四周递归遍历,获得想要的结果。

泛洪算法洛谷题型

泛洪算法洛谷题型

泛洪算法洛谷题型泛洪算法(Flood Fill Algorithm)是一种用于填充连通区域的算法,广泛应用于图像处理、游戏开发和计算机视觉等领域。

在洛谷(Loj.ac)题库中,也存在涉及泛洪算法的题型。

本文将从介绍泛洪算法的原理和应用入手,探讨洛谷题库中与泛洪算法相关的题目。

1. 泛洪算法原理泛洪算法的核心思想是从某一个起始点出发,在相邻区域内进行不断扩散,并确定相邻区域是否需要被填充。

具体步骤如下:1.1 设置起始点和填充颜色。

1.2 遍历起始点的相邻区域,如果相邻区域颜色与填充颜色相同且未被填充过,则将该区域标记为已填充,并将其加入待遍历的队列。

1.3 对待遍历的队列中的每个相邻区域,重复步骤1.2直到队列为空。

1.4 重复执行步骤1.2和1.3,直到图像中所有与起始点连通的区域被填充。

2. 泛洪算法的应用2.1 图像填充:泛洪算法可以用来识别和填充连通区域,比如图像中的闭合区域或者拓扑结构。

2.2 游戏开发:在游戏中,玩家可能需要点击某个区域,然后将与该区域相邻且颜色相同的区域都进行填充。

2.3 计算机视觉:泛洪算法可以用来对图像进行分割,实现目标检测、边缘检测等计算机视觉任务。

3. 洛谷题库中的泛洪算法题目洛谷是一个开放的在线题库,提供大量的算法题目供用户练习和挑战。

其中,涉及泛洪算法的题目主要包括以下几类:3.1 填色问题:给定一个图像和起始点,要求对与起始点连通的区域进行填色。

3.2 求解连通区域数量:给定一个图像,要求计算图像中连通区域的数量。

3.3 地图标记问题:给定一个区域地图,要求对特定类型的区域进行标记。

3.4 计算最短路径:给定一个迷宫地图,要求求解从起点到终点的最短路径长度。

4. 题目示例以下是洛谷中一个关于泛洪算法的题目示例:题目描述:给定一个二维矩阵,矩阵中的元素值代表该位置的海拔高度。

请编写程序,计算矩阵中相邻的、高度相同的区域的数量。

输入格式:第一行包含两个整数n和m,分别表示矩阵的行数和列数。

flood-filling 方法

flood-filling 方法

flood-filling 方法Flood-Filling方法一、引言Flood-Filling方法是一种图像处理算法,常用于给图像区域上色、填充或者分割等操作。

它通过选择一个起始点,然后从该点出发,逐渐向四周扩展,直到填充满整个区域。

本文将介绍Flood-Filling方法的原理、应用和相关注意事项。

二、原理Flood-Filling方法的原理是基于种子填充的思想。

首先,选择一个起始点作为种子点,将其颜色值设为目标颜色。

然后,从种子点开始,向四周扩展,将相邻且颜色相同的点设为目标颜色,直到没有符合条件的点为止。

这个过程可以使用递归或者迭代的方式实现。

三、应用1. 填充Flood-Filling方法常用于给图像中的封闭区域上色。

可以通过选择种子点和目标颜色,将区域内的所有像素点的颜色值修改为目标颜色,从而实现填充效果。

这在图像编辑软件中常用于涂抹和修复图像的功能。

2. 分割Flood-Filling方法还可以用于图像的分割。

通过选择具有特定颜色或者灰度值的种子点,可以将图像中的不同区域分割开来。

这在计算机视觉中常用于目标检测和图像分析等领域。

3. 选取区域除了填充和分割,Flood-Filling方法还可以用于选取图像中的特定区域。

通过选择种子点和目标颜色,可以将目标区域内的像素点的颜色值设为其他值,从而将其与周围区域区分开来。

这在图像处理中常用于提取感兴趣的区域或者去除背景噪声。

四、注意事项1. 边界处理使用Flood-Filling方法时,需要注意边界处理。

通常情况下,边界上的像素点不会被填充或者分割。

可以通过设置边界条件或者使用边界检测算法来解决这个问题。

2. 选择种子点选择合适的种子点对于Flood-Filling方法的效果至关重要。

种子点应该位于目标区域内,并且能够覆盖到整个区域。

通常可以通过图像分析或者用户交互的方式来选择种子点。

3. 目标颜色选择选择合适的目标颜色也是Flood-Filling方法的关键。

FloodFill(漫水填充)算法的实现

FloodFill(漫水填充)算法的实现

FloodFill(漫水填充)算法的实现简介所谓漫水填充,简单来说,就是自动选中了和种子点相连的区域,接着将该区域替换成指定的颜色,这是个非常有用的功能,经常用来标记或者分离图像的一部分进行处理或分析.漫水填充也可以用来从输入图像获取掩码区域,掩码会加速处理过程,或者只处理掩码指定的像素点.有这个填充算法为基础,类似photoshop的魔术棒选择工具就很容易实现了。

漫水填充(FloodFill)是查找和种子点联通的颜色相同的点,魔术棒选择工具则是查找和种子点联通的颜色相近的点,将和初始种子点颜色相近的点压进栈作为新种子本人认为该算法还能用于相对理想情况下的道路识别,实现汽车的无人驾驶.部分代码FloodFill用指定颜色填充一个连接域,此处用了对比鲜明的红色和绿色作为填充色void cvFloodFill( CvArr* image, CvPoint seed_point, CvScalar new_val,CvScalar lo_diff=cvScalarAll(0), CvScalar up_diff=cvScalarAll(0),CvConnectedComp* comp=NULL, int flags=4, CvArr* mask=NULL );#define CV_FLOODFILL_FIXED_RANGE (1 << 16)#define CV_FLOODFILL_MASK_ONLY (1 << 17)image输入的 1- 或 3-通道, 8-比特或浮点数图像。

输入的图像将被函数的操作所改变,除非你选择 CV_FLOODFILL_MASK_ONLY 选项 (见下面).seed_point开始的种子点.new_val新的重新绘制的象素值lo_diff当前观察象素值与其部件领域象素或者待加入该部件的种子象素之负差(Lower difference)的最大值。

对8-比特彩色图像,它是一个packed value.up_diff当前观察象素值与其部件领域象素或者待加入该部件的种子象素之正差(upper difference)的最大值。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于FLOOD Fill算法的迷宫路径求解方法研究王润民;刘占文;杨澜;惠飞【摘要】目前国际电脑鼠走迷宫竞赛中常采用的FLOOD Fill迷宫搜索算法存在硬件系统资源消耗较多和无法实现最短路径求解及判定等问题.根据FLOOD Fill算法和FLOOD Fill迷宫搜索算法的工作原理,提出修正的FLOOD Fill迷宫搜索算法及相应的最短路径求解算法.通过判断更新必要迷宫格编码值提高迷宫搜索算法的执行效率,建立“有墙迷宫”和“无墙迷宫”完成迷宫搜索后最短路径的最优性判定和迷宫搜索次数的决策.MATLAB平台的仿真分析和IEEE标准迷宫的实际测试结果表明,相对于FLOODFill迷宫搜索算法,该方法不仅减少了97%的冗余编码值更新,而且能够准确地求解出搜索后的迷宫最短路径.【期刊名称】《计算机应用与软件》【年(卷),期】2015(032)011【总页数】5页(P238-242)【关键词】电脑鼠;迷宫搜索算法;FLOOD Fill算法;最短路径求解;编码值【作者】王润民;刘占文;杨澜;惠飞【作者单位】长安大学现代工程训练中心陕西西安710018;长安大学信息工程学院陕西西安710064;长安大学信息工程学院陕西西安710064;长安大学信息工程学院陕西西安710064【正文语种】中文【中图分类】TP301.60 引言“电脑鼠”,英文名MicroMouse,是由嵌入式微处理器、传感器和电机组成的一种小型自动化轮式智能机器人。

根据国际电工和电子工程学会(IEEE)制定的电脑鼠迷宫竞赛规则,电脑鼠需要在由16×16个18 cm×18 cm大小的单元格组成的不同的未知迷宫中自行行走、搜索迷宫内部信息并寻找迷宫起点到终点的路径,以快速到达迷宫的终点[1]。

IEEE每年会举办一次国际性的电脑鼠走迷宫竞赛,在竞赛中电脑鼠需要完成迷宫路径的求解,具体包括未知迷宫的搜索和最短路径的求解两个任务,前者要求电脑鼠搜索并记忆迷宫的内部结构,寻找迷宫起点与终点之间存在的路径,后者要求电脑鼠根据搜索过程获得的迷宫墙壁资料信息寻找判断迷宫从起点到终点的最短路径。

在硬件条件确定的条件下,电脑鼠的性能优劣主要由电脑鼠的迷宫路径求解算法(包括迷宫搜索算法和最短路径求解算法)决定,其中前者反映了电脑鼠的智能性和记忆能力,后者反映了电脑鼠的运算处理能力。

迷宫路径求解问题是一个典型的组合优化问题,被广泛应用于解决管道铺设、设备安装、线路规划、智力训练等生产生活中的诸多方面[2]。

目前研究拓扑学和图论的工程师已经探讨研究了较多的迷宫路径求解算法,包括沿壁法、向心深度优先算法、Djikstra算法、FLOOD Fill 算法和遗传算法等[3]。

本文对目前电脑鼠迷宫竞赛中常用FLOOD Fill迷宫搜索算法进行分析研究,针对其应用在迷宫路径求解问题上的存在不足进行修正,然后在修正搜索算法的基础上构建了迷宫最短路径的求解方法,并通过建立MATLAB仿真平台和实物IEEE标准迷宫对改进前后的算法进行测试。

通过对算法的仿真、分析验证了修正算法的优越性。

1 FLOOD Fill算法FLOOD Fill算法又称泛洪算法,或贝尔曼算法,该算法属于一种特殊的深度优先遍历算法,利用了水流从水源近处流向远处的原理[4]。

假设洪水从迷宫中的某一个格子源源不断地流出,那么洪水就会向有路的地方流动,而且洪水会首先到达离洪水涌出点最近的迷宫格,最后到达离洪水涌出点最远的迷宫格。

利用此原理可以按照迷宫布局建立一个编码表,将洪水涌出迷宫格编码标记为0,洪水每流动到下一格就将该迷宫格编码标记为上一迷宫格的编码值加1。

以一个8×8大小迷宫为例,如图1(a)所示,假设该迷宫中洪水涌出点为F,将该格编码值标记为0,“洪水”从此点开始向相邻迷宫格流动,每流过一个迷宫单元格就标定该单元格的编码值为上一个迷宫单元格的编码值加1,以此类推,就可以计算出每一个迷宫格的编码值,如图1(b)所示。

实际上迷宫单元格的编码值代表了该单元格与洪水涌出迷宫格的距离值,因此依据每一个迷宫格与迷宫洪水涌出点的距离值(编码值),再以由大到小的方式排列,即可找到已知迷宫中任意迷宫格与洪水涌出迷宫格间的最短路径。

图1(c)中灰色线条表示通过FLOOD Fill算法求解得到的迷宫右上角单元格与洪水涌出迷宫格间的最短路径。

通过将已知迷宫中的任意迷宫格定义为洪水涌出点,即可找到迷宫中任意两个迷宫格之间的最短路径。

图1 FLOOD Fill算法原理示意图2 迷宫搜索算法2.1 FLOOD Fill迷宫搜索算法FLOOD Fill迷宫搜索算法是一种以FLOOD Fill算法为核心实现对未知迷宫进行搜索的算法。

为了简化问题的说明,以一个5×5的迷宫为例,如图2(a)所示,以左下角的迷宫格为原点建立一个正向坐标系,每一组坐标(x,y)表示了该位置的迷宫格,其中(0,0)为迷宫的起点S,(2,2)为迷宫的终点G。

在电脑鼠开始搜索迷宫之前,FLOOD Fill迷宫搜索算法首先建立一个5×5的矩阵作为迷宫编码表,用于存储FLOOD Fill算法执行后各迷宫格的编码值。

然后假设迷宫内部没有墙壁并以迷宫终点为洪水涌出点执行FLOOD Fill算法,结果如图2(b)所示,其中迷宫内部的数据表示第一次执行FLOOD Fill算法后各迷宫格的编码值[5]。

图2 示例迷宫及初始编码表随后FLOOD Fill迷宫搜索算法驱动电脑鼠从起点开始运行并探索迷宫,直至搜索到终点。

在搜索过程中需要遵循以下规则。

规则1:a)电脑鼠每进入一个迷宫格就检测当前迷宫格的墙壁信息,然后在当前探索到的所有迷宫墙壁信息的基础上以迷宫终点为洪水涌出点执行一次FLOOD Fill算法,更新编码表;b)电脑鼠选择比当前迷宫格编码值小的相邻迷宫格前进,若比当前迷宫格编码值小的相邻迷宫格不止1个,则选择编码值最小的迷宫格前进;若编码值最小的迷宫格存在不止1个,则随机选择一个方向进入,并返回a执行。

具体搜索过程如图3所示,电脑从起点(0,0)开始运行,在此处检测到右边存在墙壁,然后执行一次FLOOD Fill算法,更新编码表,结果如图3(a)所示。

在(0,0)处仅存在一个可前进的迷宫格(0,1),因此移动到该迷宫格,检测到上方有墙,并根据迷宫墙壁信息执行一次FLOOD Fill算法,结果如图3(b)所示。

在(0,1)处存在两个相邻的迷宫格(0,0)和(1,1),但根据规则1.a,可前进的迷宫格为(1,1),于是电脑鼠移动到该迷宫格,检测到右方有墙,并根据此时的迷宫墙壁信息执行一次FLOOD Fill算法,更新编码表,结果如图3(c)所示。

在(1,1)处仅存在一个可前进的方向(1,2),于是电脑鼠移动到该迷宫格,此时检测到右方和上方有墙,然后根据此时的迷宫墙壁信息执行一次FLOOD Fill算法,更新编码表,结果如图3(d)所示,电脑鼠在(1,2)的左方和后方存在两个优先级相同的可前进方向,则随机选择一个方向前进。

图3 FLOOD Fill迷宫搜索算法执行过程按照上述方式,电脑鼠每进入一个新的迷宫格就检测迷宫墙壁信息,然后执行FLOOD Fill算法并更新编码表,判定前进方向并进入下一迷宫格继续进行上述过程,直至搜索到迷宫终点(2,2)。

电脑鼠在(1,2)处分别选择(0,2)和(1,1)两个方向前进时得到的最终搜索结果如图4所示,其中灰色线表示相应的搜索过程中电脑鼠走过的路径。

图4 FLOOD Fill迷宫搜索算法搜索结果电脑鼠采用FLOOD Fill迷宫搜索算法对图2(a)所示的迷宫进行搜索的过程中(以图4(a)所示的结果为例),电脑鼠从起点到终点一共走过了11个迷宫格,进行了11次FLOOD Fill迷宫算法,更新了11×25=275个迷宫格编码值,若将FLOOD Fill 迷宫搜索算法应用到16×16大小的迷宫,电脑鼠进行一次搜索需要更新数十万个编码值[6]。

然而实际上相当多的编码值重算和更新过程并不是必需的,例如电脑鼠运行至(0,1)和(1,1)时更新的全部编码值与更新前相比没有任何变化,如图3(a)-(c)所示;再如电脑鼠运行至(1,2)时更新的全部的编码值仅部分发生了变化,如图3(c)和图3(d)所示。

大量冗余编码值的更新需要耗用较多的算法处理时间和电脑鼠系统资源,然而考虑到造价及开发难度等因素电脑鼠一般被设计为具有较小的运算处理能力,因此需要考虑仅在需要更新的时候才对需要更新的迷宫格的编码值进行重算赋值,减少电脑鼠的冗余计算,提高其运算处理效率[7]。

2.2 修正的FLOOD Fill迷宫搜索算法针对上述问题,提出修正的FLOOD Fill迷宫搜索算法。

该算法不仅需要在电脑鼠开始搜索迷宫之前建立一个5×5的矩阵作为迷宫编码表,还需要在电脑鼠正式运行之前在内存中建立一个堆栈。

然后电脑鼠在迷宫起点设定迷宫内无墙壁,并执行一次FLOOD Fill算法并填充编码表,填充完毕后开始正式运行。

电脑鼠每到达一个新的迷宫格时不再以迷宫终点为洪水涌出点执行FLOOD Fill算法,而是按照如下规则进行判断处理执行,直至运动至迷宫终点。

规则2:a)将当前迷宫格的坐标值(m,n)压入堆栈,并检测当前迷宫格的墙壁信息;b)将堆栈顶端的坐标值(x,y)弹出,判断与(x,y)相邻接连通且编码值最小的迷宫格的编码值MC是否等于(x,y)迷宫格的编码值减1,如果不相等,就将(x,y)迷宫格的编码值赋值为MC+1,并把上下左右四个相邻迷宫格(终点迷宫格除外)的位置坐标压入堆栈,否则直接转入c执行;c)判断堆栈是否为空,如果不为空则返回b执行。

如果为空则选择与当前迷宫格连通且比当前迷宫格编码值小的相邻迷宫格前进,若可供选择的迷宫格不止1个,则选择编码值最小的迷宫格进入(若存在多个,则随机选择一个进入),然后返回a执行。

以图2(a)所示的迷宫为例说明:按照规则2,电脑鼠进入(0,0)、(0,1)、(1,1)迷宫格后,当前迷宫格的编码值减1均与其相邻连通且编码值最小的迷宫格的编码值相等,并且堆栈为空,因此电脑鼠不需要更新迷宫编码表,直至运行至迷宫格(1,2)。

在进入迷宫格(1,2)时,电脑鼠将坐标(1,2)压入栈顶,如图5(a)所示,其中灰色三角形表示电脑鼠。

与迷宫格(1,2)相邻接的编码值最小的连通迷宫格为(1,1)和(0,2),其编码值MC为2,而(1,2)的编码值减1为0,二者不相等,因此需要将迷宫格(1,2)的编码值更新为MC+1=3,同时将迷宫格(1,2)上下左三个相邻迷宫格的坐标压入堆栈,结果如图5(b)所示,其中灰色圆代表当前坐标被压栈的迷宫格。

继续按规则2执行,直至堆栈再一次为空,执行结果如图5(c)所示,其中灰色区域表示电脑鼠在(1,2)处时编码值被更新的迷宫格,然后电脑鼠按规则2选择下一个迷宫格前进。

相关文档
最新文档