用栈、回溯算法设计迷宫程序

简介: 用栈、回溯算法设计迷宫程序

目录

1、走迷宫与回溯算法


2、迷宫设计栈扮演的角色


3、Python实现走迷宫


栈的应用有许多,本篇博文着重将栈与回溯(Backtracking)算法结合,设计走迷宫程序。其实回溯算法也是人工智能的一环,通常又称试错(try and error)算法,早期设计的计算机象棋游戏、五子棋游戏,大都是使用回溯算法。


1、走迷宫与回溯算法

假设一个简单的迷宫图形如下图所示:


image.png


一个迷宫基本上由4种空格组成:


入口:迷宫的入口,笔者上图用绿色表示。
通道:迷宫的通道,笔者上图用黄色表示。
墙壁:迷宫的墙壁,不可通行,笔者上图用灰色表示。
出口:迷宫的出口,笔者上图用蓝色表示。

在走迷宫时,可以上、下、左、右行走,如下图所示:


image.png


走迷宫时每次可以走一步,如果碰到墙壁不能穿越必须走其他方向。


第1步:假设目前位置在入口处,可以参考下图所示:


image.png


第2步:如果依照上、下、左、右原则,应该向上走,但是往上是墙壁,所以必须往下走,然后必须将走过的路标记,此例是用浅绿色标记,所以上述右图是在迷宫中的新位置,如下图所示:


image.png


第3步:接下来可以发现往上是走过的路,所以只能往下发(依据上、下、左、右原则,先不考虑左、右是墙壁),下方左图是新的迷宫位置,如下图所示:


image.png


第4步:接下来可以发现往上是走过的路,所以只能往下(依据上、下、左、右原则,先不考虑左、右),下方右图是新的迷宫位置,如下图所示:


image.png


第5步:现在下、左、右皆是墙壁,所以回到前面走过的路,这一步就是回溯的关键,可参考下方左图,在此图中笔者将造成回溯的路另外标记,以防止再次造访,如下图所示:


image.png


第6步:现在上、下皆是走过的路,左边是墙壁,所以往右走,如下图所示:


image.png


第7步:接下来上、下是墙壁,左边是走过的路,所以往右走,如下图所示:


image.png


第8步:由于上方有路所以往上走,如下图所示:


image.png


第9步:由于上方有路所以往上走,如下图所示:


image.png


第10步:由于上、左、右皆是墙壁,所以回溯到前一个位置,如下图所示:


image.png


第11步:由于上、下是走过的路,左边是墙壁,所以往右走,如下图所示:


image.png


第12步:由于上、下、右是墙壁,所以回溯到先前位置,如下图所示:


image.png


第13步:由于左边是墙壁,所以回溯到先前走过的位置,如下图所示:


image.png


第14步:下方有通道,所以往下走,如下图所示:


image.png


第15步:上方是走过的位置,左方和下方是墙壁,所以往右走,如下图所示:


image.png


2、迷宫设计栈扮演的角色

上面介绍到,在第2步使用浅绿色标记走过的路,真实程序设计可以用栈存储走过的路。


第5步使用回溯算法,所谓的回溯就是走以前走过的路,因为是将走过的路使用栈(stack)存储,基于后进先出原则,可以pop出前一步路径,这也是回溯的重点。当走完第4步时,


迷宫与栈图形如下所示:


image.png


上述迷宫位置使用程序语言的(row,column)标记,所以第5步要使用回溯时,可以从栈pop出(3,1)坐标,回到(3,1)位置,结果如下所示所示:


image.png


3、Python实现走迷宫

使用Python设计走迷宫可以使用二维的列表,0代表通道、1代表墙壁,至于起点和终点也可以用0代表。


使用上述第一部分的迷宫实例,其中所经过的路径用2表示,经过会造成无路可走的路径用3表示。程序第41行前2个参数是迷宫的入口,后2个参数是迷宫的出口,实现代码如下所示:


# ch11_1.py
from pprint import pprint
maze = [                                    # 迷宫地图
        [1, 1, 1, 1, 1, 1],
        [1, 0, 1, 0, 1, 1],
        [1, 0, 1, 0, 0, 1],
        [1, 0, 0, 0, 1, 1],
        [1, 0, 1, 0, 0, 1],
        [1, 1, 1, 1, 1, 1]
       ] 
directions = [                              # 使用列表设计走迷宫方向
              lambda x, y: (x-1, y),        # 往上走
              lambda x, y: (x+1, y),        # 往下走
              lambda x, y: (x, y-1),        # 往左走
              lambda x, y: (x, y+1),        # 往右走       
             ]
def maze_solve(x, y, goal_x, goal_y):
    ''' 解迷宫程序 x, y是迷宫入口, goal_x, goal_y是迷宫出口'''
    maze[x][y] = 2
    stack = []                              # 建立路径栈
    stack.append((x, y))                    # 将路径push入栈
    print('迷宫开始')
    while (len(stack) > 0):
        cur = stack[-1]                     # 目前位置
        if cur[0] == goal_x and cur[1] == goal_y:
            print('抵达出口')
            return True                     # 抵达出口返回True        
        for dir in directions:              # 依上, 下, 左, 右优先次序走此迷宫
            next = dir(cur[0], cur[1])
            if maze[next[0]][next[1]] == 0: # 如果是通道可以走
                stack.append(next)
                maze[next[0]][next[1]] = 2  # 用2标记走过的路
                break
        else:                               # 如果进入死路, 则回溯
            maze[cur[0]][cur[1]] = 3        # 标记死路
            stack.pop()                     # 回溯 
    else:
        print("没有路径")
        return False
maze_solve(1, 1, 4, 4)
pprint(maze)                                # 跳行显示元素

运行效果如下所示:

image.png

相关文章
|
2月前
|
存储 算法 C语言
"揭秘C语言中的王者之树——红黑树:一场数据结构与算法的华丽舞蹈,让你的程序效率飙升,直击性能巅峰!"
【8月更文挑战第20天】红黑树是自平衡二叉查找树,通过旋转和重着色保持平衡,确保高效执行插入、删除和查找操作,时间复杂度为O(log n)。本文介绍红黑树的基本属性、存储结构及其C语言实现。红黑树遵循五项基本规则以保持平衡状态。在C语言中,节点包含数据、颜色、父节点和子节点指针。文章提供了一个示例代码框架,用于创建节点、插入节点并执行必要的修复操作以维护红黑树的特性。
66 1
|
5天前
|
算法 JavaScript 前端开发
第一个算法项目 | JS实现并查集迷宫算法Demo学习
本文是关于使用JavaScript实现并查集迷宫算法的中国象棋demo的学习记录,包括项目运行方法、知识点梳理、代码赏析以及相关CSS样式表文件的介绍。
第一个算法项目 | JS实现并查集迷宫算法Demo学习
|
6天前
|
算法 前端开发
一文了解贪心算法和回溯算法在前端中的应用
该文章深入讲解了贪心算法与回溯算法的原理及其在前端开发中的具体应用,并通过分析LeetCode题目来展示这两种算法的解题思路与实现方法。
|
2月前
|
算法
【算法】递归、搜索与回溯——汉诺塔
【算法】递归、搜索与回溯——汉诺塔
|
2月前
|
算法
【算法】递归、搜索与回溯——简介
【算法】递归、搜索与回溯——简介
|
2月前
|
算法
【算法】栈算法——逆波兰表达式求值
【算法】栈算法——逆波兰表达式求值
|
2月前
|
存储 算法
【算法】栈算法——最小栈
【算法】栈算法——最小栈
|
2月前
|
算法
【算法】栈算法——栈的压入、弹出序列
【算法】栈算法——栈的压入、弹出序列
|
2月前
|
算法 Python
【python】python基于 Q-learning 算法的迷宫游戏(源码+论文)【独一无二】
【python】python基于 Q-learning 算法的迷宫游戏(源码+论文)【独一无二】
|
3月前
|
算法 索引 Python
逆袭算法界!Python分治法、贪心算法、动态规划深度剖析,带你走出算法迷宫!
【7月更文挑战第8天】分治法,如快速排序,将大问题分解并合并解;贪心算法,选择局部最优解,如活动选择;动态规划,利用最优子结构避免重复计算,如斐波那契数列。Python示例展示这些算法如何解决实际问题,助你精通算法,勇闯迷宫。
34 1
下一篇
无影云桌面