Python实现迷宫自动寻路实例

 更新时间:2022年02月08日 14:16:14   作者:程序媛小本  
大家好,本篇文章主要讲的是Python实现迷宫自动寻路实例,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下

背景

我打开手机,发现有人在QQ空间里叫嚣。

看他得意的样子,显然是在家里呆久了,已经忘了天有多高。

预处理

设计一个迷宫自动寻路算法并不难,但是对于当下这个任务而言,第一个棘手的地方在于,如何把这个迷宫变成计算机认识的样子,也就是迷宫图片的矩阵化。

图片的大小是397×390。先把四周的白边裁掉,再把这幅图中的每一个像素二值化,再根据颜色赋值,黑色用0表示,白色用1表示,建立一个0/1矩阵。考虑到迷宫的边界都是封闭的,为了防止由于图片质量问题导致某些看上去是0的地方其实是1,在之后走迷宫的过程中造成一些可预知的影响,比如列表的越界等,我们再把四条边上的元素全部强制变成0。这时,对迷宫的预处理已经基本完成,如果我们把1隐藏,把所有的0打印出来,经过放缩之后,就得到了这样的结果:

寻路算法

得到了这个迷宫矩阵之后,我们需要找到一条从左上角到右下角的路。

印象中我与有关走迷宫的方法有过一面之缘,那是在一节算法选修课上,老师在台上深情地讲着深度优先搜索与广度优先搜索,我在台下忘我地抄着大物实验报告。至今,提起这两个概念,我唯一的印象只有它俩的英文缩写一个是D开头一个是B开头。

不过没关系。当年陈刀仔他能用20块赢到3700万,我用for循环搞定这个小迷宫,没有问题。

一般来说,迷宫的内部是不封闭的,我从任意一个地方倒水,总能把整个迷宫填满。因此,假定我们有一个小老鼠,把它放在起点,如果它能够保证自动避障、不踩走过的路、遇死胡同回退,那么它总能找到终点。

因此,我们定义一个点(x,y),初始位置为(1,1),也就是边界内左上角的第一个点。

定义两个列表,一个是path,用来存放它最终确定下来的路径(也就是那个最终走到终点的路径)中的每一个点;另一个是footprint,用来存放所有它走过的地方,包括它走的错路。两个列表形如[(1,1),(1,2),(2,2),......,(m,n)]

再定义四种动作,分别是:向下走一步(y=y+1),向右走一步(x=x+1),向左走一步(x=x-1)和向上走一步(y=y-1)。我们每次让这个点尝试四种动作,如果能走就让它走。判断是否不能走是看下一步的坐标是否是墙或者是足迹。把新的点放进pathfootprint里,成为新的足迹。

确定四个动作的优先级,即下、右、左、上,能下则下,不能下则右,不能右则左,不能左则上。这样它就不会在一个空地上平白无故地乱转,而是具有一定方向性地探索。

接下来,让算法具备自动回退的能力。我们想象一个简单情景:

这个图不准确,不满足本文的优先级设定,但也足以表意

遇到这样的死胡同,假如进来的时候足迹把出去的路给封死了,那么这个点就没办法再出来了。一旦我们发现这个点陷入了绝境,哪里都不能走了,这时候我们就得让它原路返回。实迷途其未远,回到上一个路口也很简单,无非就是删掉这一段路线。方法就是把path列表里的最后一个元素逐一弹出列表,由于我们有footprint记录,所有它走过的地方都不能再走第二遍,所以只要这条错误的路没有完全退出去,退到哪一步都是四个方向都不能走的,因为附近都被它走过了。这样它就会一直退到我们期望的那个地方,也就是它误入歧途的那个路口。

测试

下面,我们让它开始循环。只要它的坐标不等于终点的坐标,我们就一直让它不断地探索。运行结束后,我们得到了一条迂回的曲线,如图(局部)。

程序成功得到了一条可以通往终点的路径,但这条路径过于冗杂,以上图为例,所有宽度不为1的地方都是这个点绕来绕去所导致的。因此,该路径还有待优化。

优化

我们考虑如下一种简单情况:

在这条路线中,显然4~9属于没有意义的兜圈,正确的路线应该是从3直接到10

我们的优化方法是:如果第n步(x,y),从第n+2步(也就是下一步的下一步),一直到最后一步,这中间只要有一步落在(x,y)一步之遥的地方,就把从第n+1步到这一步的所有路径点都删掉。拿上面这个例子来说,我们从第1步开始检查。检查到第3步时,我们从第5步开始看,一直看到第10步发现10落在3一步就能到达的地方,这时我们把中间的4-9全部删掉,直接把10接在3的后面。

不过,考虑到后面可能还会有更优的情况,比如说从12开始继续绕,绕到20发现20刚好落在3的上面,那我们事实上应该直接把20接在3后面,12也要丢掉,之前的方法有些缺陷。因此,为了避免这种情况,我们逆着循环,对于第3步而言,我们从第20步往前循环,一直循环到第5步,看是否有3能直接到达的地方。这样我们就能对这条路线进行最大优化了。

绘制路径

最终,我们得到了正确而简洁的路径,也记录了曾经走过的错路和多走的路。

根据矩阵和图片的对应关系,我们把图片里对应的像素改变颜色,其它点不作更改。

绘制路径:

优化之前:

全部足迹:

结语

至此,我们已经把这个问题解决得差不多了。整个程序在我的电脑上运行下来大概需要三五分钟这个样子,毕竟是只用for循环的暴力方法。

相关文章

  • Django ModelSerializer实现自定义验证的使用示例

    Django ModelSerializer实现自定义验证的使用示例

    本文主要介绍了Django ModelSerializer实现自定义验证的使用示例,多种字段验证器帮助开发者确保数据的完整性和准确性,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • Python操作PDF实现制作数据报告

    Python操作PDF实现制作数据报告

    Python操作PDF的库有很多,比如PyPDF2、pdfplumber、PyMuPDF等等。本文将利用FPDF模块操作PDF实现制作数据报告,感兴趣的小伙伴可以尝试一下
    2022-12-12
  • Python 文件重命名工具代码

    Python 文件重命名工具代码

    Python 文件重命名工具实现代码。
    2009-07-07
  • 详解Python openpyxl库的基本应用

    详解Python openpyxl库的基本应用

    这篇文章主要介绍了Python openpyxl库的基本应用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-02-02
  • 基于PyQt5制作一个猜数字小游戏

    基于PyQt5制作一个猜数字小游戏

    这篇文章主要为大家介绍了如何用Python中的PyQt5模块制作一个带GUI的猜数字小游戏,文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-03-03
  • Python中统计函数运行耗时的方法

    Python中统计函数运行耗时的方法

    这篇文章主要介绍了Python中统计函数运行耗时的方法,涉及Python时间操作的相关技巧,非常简单实用,需要的朋友可以参考下
    2015-05-05
  • 使用Python从零开始撸一个区块链

    使用Python从零开始撸一个区块链

    对数字货币的崛起感到新奇的我们,并且想知道其背后的技术——区块链是怎样实现的。这篇文章主要介绍了使用Python从零开始撸一个区块链,需要的朋友可以参考下
    2018-03-03
  • python在windows调用svn-pysvn的实现

    python在windows调用svn-pysvn的实现

    本文主要介绍了python在windows调用svn-pysvn的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • python设计模式之装饰器模式

    python设计模式之装饰器模式

    这篇文章主要介绍了python设计模式之装饰器模式,文章基于python得设计模式资料展开饰器模式得详细资料,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • Python实现UDP程序通信过程图解

    Python实现UDP程序通信过程图解

    这篇文章主要介绍了Python实现UDP程序通信过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05

最新评论