迷宫问题

简介: 迷宫问题是指在给定区域内寻找从起点到终点的可行路径。可以使用回溯算法解决,通过不断尝试四个方向(上下左右)移动,若无法前进则回退,直到找到终点或遍历所有可能路径。文中还给出了C语言、Java和Python的实现代码,并展示了运行结果。

迷宫问题指的是:在给定区域内,找到一条甚至所有从某个位置到另一个位置的移动路线。举个简单的例子,如图 1 所示,在白色区域内找到一条(甚至所有)从起点到终点的路线。


图1:迷宫问题


迷宫问题就可以采用回溯算法解决,即从起点开始,采用不断“回溯”的方式逐一试探所有的移动路线,最终找到可以到达终点的路线。

回溯算法解决迷宫问题

以图 1 所示的迷宫为例,回溯算法解决此问题的具体思路是:

  1. 从当前位置开始,分别判断是否可以向 4 个方向(上、下、左、右)移动:
  2. 选择一个方向并移动到下个位置。判断此位置是否为终点,如果是就表示找到了一条移动路线;如果不是,在当前位置继续判断是否可以向 4 个方向移动;
  3. 如果 4 个方向都无法移动,则回退至之前的位置,继续判断其它的方向;
  4. 重复 2、3 步,最终要么成功找到可行的路线,要么回退至起点位置,表明所有的路线都已经判断完毕。


程序中,我们可以用特殊的字符表示迷宫中的不同区域。例如,用 1 表示可以移动的白色区域,用 0 表示不能移动的黑色区域,图 1 的迷宫可以用如下的 0-1 矩阵来表示:

1 0 1 1 1

1 1 1 0 1

1 0 0 1 1

1 0 0 1 0

1 0 0 1 1

如下是用回溯算法解决迷宫问题的伪代码:

输入 maze[ROW][COL]   //输入迷宫地图,0 表示黑色区域,1 表示可行走区域

//(row,col) 表示起点,(outrow,outcol)表示终点

maze_puzzle(maze,row,col,outrow,outcol):

   //回溯过程中,行走的每一区域都设为 Y,表示已经进行了判断

   maze[row][col] <- 'Y'

   //如果行走至终点,表明有从起点到终点的路线

   if row == outrow && col == outcol:

       Print maze  // 输出行走路线

       return

   //判断是否可以向上移动

   if canMove(maze,row-1,col):

       maze_puzzle(maze,row-1,col,outrow,outcol)

   //判断是否可以向左移动

   if canMove(maze,row,col-1):

       maze_puzzle(maze,row,col-1,outrow,outcol)

   //判断是否可以向下移动

   if canmove(maze,row+1,col):

       maze_puzzle(maze,row+1,col,outrow,outcol)

   //判断是否可以向右移动

   if canmove(maze,row,col+1):

       maze_puzzle(maze,row,col+1,outrow,outcol)


结合伪代码,如下为解决迷宫问题的 C 语言程序:

  1. #include <stdio.h>
  2. typedef enum { false, true } bool;
  3. #define ROW 5
  4. #define COL 5
  5. //假设当前迷宫中没有起点到终点的路线
  6. bool find = false;
  7. //回溯算法查找可行路线
  8. void maze_puzzle(char maze[ROW][COL], int row, int col, int outrow, int outcol);
  9. //判断 (row,col) 区域是否可以移动
  10. bool canMove(char maze[ROW][COL], int row, int col);
  11. //输出行走路线
  12. void printmaze(char maze[ROW][COL]);
  13. int main()
  14. {
  15. char maze[ROW][COL] = {
  16. {'1','0','1','1','1'},
  17. {'1','1','1','0','1'},
  18. {'1','0','0','1','1'},
  19. {'1','0','0','1','0'},
  20. {'1','0','0','1','1'} };
  21. maze_puzzle(maze, 0, 0, ROW - 1, COL - 1);
  22. if (find == false) {
  23. printf("未找到可行线路");
  24. }
  25. return 0;
  26. }

  27. //(row,col) 表示起点,(outrow,outcol)表示终点
  28. void maze_puzzle(char maze[ROW][COL], int row, int col, int outrow, int outcol) {
  29.    maze[row][col] = 'Y'; // 将各个走过的区域标记为 Y
  30. //如果行走至终点,表明有从起点到终点的路线
  31. if (row == outrow && col == outcol) {
  32.        find = true;
  33. printf("成功走出迷宫,路线图为:\n");
  34. printmaze(maze);
  35. return;
  36. }
  37. //尝试向上移动
  38. if (canMove(maze, row - 1, col)) {
  39. maze_puzzle(maze, row - 1, col, outrow, outcol);
  40. //如果程序不结束,表明此路不通,恢复该区域的标记
  41.        maze[row - 1][col] = '1';
  42. }
  43. //尝试向左移动
  44. if (canMove(maze, row, col - 1)) {
  45. maze_puzzle(maze, row, col - 1, outrow, outcol);
  46. //如果程序不结束,表明此路不通,恢复该区域的标记
  47.        maze[row][col - 1] = '1';
  48. }
  49. //尝试向下移动
  50. if (canMove(maze, row + 1, col)) {
  51. maze_puzzle(maze, row + 1, col, outrow, outcol);
  52. //如果程序不结束,表明此路不通,恢复该区域的标记
  53.        maze[row + 1][col] = '1';
  54. }
  55. //尝试向右移动
  56. if (canMove(maze, row, col + 1)) {
  57. maze_puzzle(maze, row, col + 1, outrow, outcol);
  58. //如果程序不结束,表明此路不通,恢复该区域的标记
  59.        maze[row][col + 1] = '1';
  60. }
  61. }

  62. //判断 (row,col) 区域是否可以移动
  63. bool canMove(char maze[ROW][COL], int row, int col) {
  64. //如果目标区域位于地图内,不是黑色区域,且尚未行走过,返回 true:反之,返回 false
  65. return row >= 0 && row <= ROW - 1 && col >= 0 && col <= COL - 1 && maze[row][col] != '0' && maze[row][col] != 'Y';
  66. }

  67. //输出可行的路线
  68. void printmaze(char maze[ROW][COL]) {
  69. int i, j;
  70. for (i = 0; i < ROW; i++) {
  71. for (j = 0; j < COL; j++) {
  72. printf("%c ", maze[i][j]);
  73. }
  74. printf("\n");
  75. }
  76. }


如下为解决迷宫问题的 Java 程序:

  1. public class Demo {
  2. static boolean find = false;
  3. static int ROW = 5;
  4. static int COL = 5;
  5. //(row,col) 表示起点,(outrow,outcol)表示终点
  6. public static void maze_puzzle(char [][] maze, int row, int col, int outrow, int outcol) {
  7.        maze[row][col] = 'Y'; // 将各个走过的区域标记为 Y
  8. //如果行走至终点,表明有从起点到终点的路线
  9. if (row == outrow && col == outcol) {
  10.            find = true;
  11.            System.out.println("成功走出迷宫,路线图为:");
  12. printmaze(maze);
  13. return ;
  14. }
  15. //尝试向上移动
  16. if (canMove(maze, row - 1, col)) {
  17. maze_puzzle(maze, row - 1, col, outrow, outcol);
  18. //如果程序不结束,表明此路不通,恢复该区域的标记
  19.            maze[row - 1][col] = '1';
  20. }
  21. //尝试向左移动
  22. if (canMove(maze, row, col - 1)) {
  23. maze_puzzle(maze, row, col - 1, outrow, outcol);
  24. //如果程序不结束,表明此路不通,恢复该区域的标记
  25.            maze[row][col - 1] = '1';
  26. }
  27. //尝试向下移动
  28. if (canMove(maze, row + 1, col)) {
  29. maze_puzzle(maze, row + 1, col, outrow, outcol);
  30. //如果程序不结束,表明此路不通,恢复该区域的标记
  31.            maze[row + 1][col] = '1';
  32. }
  33. //尝试向右移动
  34. if (canMove(maze, row, col + 1)) {
  35. maze_puzzle(maze, row, col + 1, outrow, outcol);
  36. //如果程序不结束,表明此路不通,恢复该区域的标记
  37.            maze[row][col + 1] = '1';
  38. }
  39. }
  40. //判断(row,col)区域是否可以移动
  41. public static boolean canMove(char [][] maze, int row, int col) {
  42. //如果目标区域位于地图内,不是黑色区域,且尚未移动过,返回 true:反之,返回 false
  43. return row >= 0 && row <= ROW - 1 && col >= 0 && col <= COL - 1 && maze[row][col] != '0' && maze[row][col] != 'Y';
  44. }
  45. //输出行走路线
  46. public static void printmaze(char [][] maze) {
  47. for(int i=0;i<ROW;i++) {
  48. for(int j=0;j<COL;j++) {
  49.                System.out.print(maze[i][j]+" ");
  50. }
  51.            System.out.println();
  52. }
  53. }
  54. public static void main(String[] args) {
  55. char [][]maze = new char[][]{
  56. {'1','0','1','1','1'},
  57. {'1','1','1','0','1'},
  58. {'1','0','0','1','1'},
  59. {'1','0','0','1','0'},
  60. {'1','0','0','1','1'} };
  61. maze_puzzle(maze, 0, 0, ROW - 1, COL - 1);
  62. if (find == false) {
  63.            System.out.print("未找到可行线路");
  64. }
  65. }
  66. }


如下为解决迷宫问题的 Python 程序:

  1. #指定地图的行数和列数
  2. ROW = 5
  3. COL = 5
  4. #初始化地图
  5. maze =[['1','0','1','1','1'],
  6. ['1','1','1','0','1'],
  7. ['1','0','0','1','1'],
  8. ['1','0','0','1','0'],
  9. ['1','0','0','1','1']]
  10. #假设当前迷宫中没有起点到终点的路线
  11. find = False
  12. #回溯算法查找可行路线
  13. def maze_puzzle(maze,row,col,outrow,outcol):
  14. global find
  15.    maze[row][col] = 'Y'
  16. if row == outrow and col == outcol:
  17.        find = True
  18. print("成功走出迷宫,路线图为:")
  19. printmaze(maze)
  20. return
  21. if canMove(maze,row-1,col):
  22. maze_puzzle(maze, row - 1, col, outrow, outcol)
  23. #如果程序不结束,表明此路不通,恢复该区域的标记
  24.        maze[row - 1][col] = '1'
  25. if canMove(maze, row, col - 1):
  26. maze_puzzle(maze, row, col - 1, outrow, outcol)
  27. #如果程序不结束,表明此路不通,恢复该区域的标记
  28.        maze[row][col - 1] = '1'
  29. #尝试向下移动
  30. if canMove(maze, row + 1, col):
  31. maze_puzzle(maze, row + 1, col, outrow, outcol)
  32. #如果程序不结束,表明此路不通,恢复该区域的标记
  33.        maze[row + 1][col] = '1'
  34. #尝试向右移动
  35. if canMove(maze, row, col + 1):
  36. maze_puzzle(maze, row, col + 1, outrow, outcol)
  37. #如果程序不结束,表明此路不通,恢复该区域的标记
  38.        maze[row][col + 1] = '1'

  39. #判断(row,col)区域是否可以移动
  40. def canMove(maze,row,col):
  41. return row >= 0 and row <= ROW - 1 and col >= 0 and col <= COL - 1 and maze[row][col] != '0' and maze[row][col] != 'Y'

  42. #输出行走路线
  43. def printmaze(maze):
  44. for i in range(0,ROW):
  45. for j in range(0,COL):
  46. print(maze[i][j],end=" ")
  47. print()

  48. maze_puzzle(maze,0,0,ROW-1,COL-1)
  49. if find == False:
  50. print("未找到可行路线")


以上程序的执行结果均为:

成功走出迷宫,路线图为:

Y 0 Y Y Y

Y Y Y 0 Y

1 0 0 Y Y

1 0 0 Y 0

1 00 Y Y

多个 Y 组成的路线就是从起点到终点的可行路线。

相关文章
|
1月前
|
消息中间件 负载均衡
RabbitMQ的工作模型?
RabbitMQ 核心模型包括交换机、队列和绑定,支持五种消息模式:简单队列、工作队列、发布/订阅、路由和主题模式,适用于不同场景的消息通信与分发。
493 0
|
1月前
|
算法 Java C语言
弗洛伊德算法求最短路径
弗洛伊德算法用于寻找加权图中各顶点间的最短路径,适用于无向图和有向图。算法基于动态规划思想,通过枚举中间顶点来更新路径,确保最终得到最短路径。该算法要求路径权值非负,否则可能出错。
105 0
|
1月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
本文内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
246 15
|
1月前
|
人工智能 运维 Cloud Native
阿里云Serverless计算产品入选Gartner®报告「领导者」象限!
近日,Gartner® 发布了 2025 年度全球《云原生应用平台魔力象限》报告,阿里云凭借 Serverless 应用引擎 SAE(以下简称 SAE)和函数计算 FC,成为亚太地区唯一入选「领导者象限」的科技公司。
183 16
|
1月前
|
人工智能 Kubernetes Cloud Native
MSE Nacos Controller:为 Kubernetes 生态构建配置管理与服务发现的桥梁
在企业云原生转型过程中,如何实现传统微服务与 Kubernetes 服务的配置统一管理、服务互通及协议转换成为关键挑战。MSE Nacos Controller 应运而生,作为连接 Kubernetes 与 Nacos 的桥梁,支持 ConfigMap 与 Nacos 配置双向同步、服务自动注册发现,并助力 Higress 等 MCP 网关实现 REST API 向 AI 可调用 MCP 服务的转换,全面提升系统治理能力与智能化水平。
212 32
|
1月前
|
人工智能 缓存 JavaScript
Function AI 助力用户自主开发 MCP 服务,一键上云高效部署
在 AI 与云原生融合的趋势下,开发者面临模型协同与云端扩展的挑战。MCP(模型上下文协议)提供统一的交互规范,简化模型集成与服务开发。Function AI 支持 MCP 代码一键上云,提供绑定代码仓库、OSS 上传、本地交付物部署及镜像部署等多种构建方式,助力开发者高效部署智能服务,实现快速迭代与云端协同。
274 22
|
1月前
|
Cloud Native 测试技术 开发者
云原生 LFX Mentorship 招募中:开源影响力与丰厚报酬兼得,开发者不容错过!
参与其中的开发者不仅有机会在经验丰富的社区 Mentor 指导下贡献开源项目、为职业生涯加分,完成课题后还能获得丰厚酬劳。
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
AI 基础知识从 0.3 到 0.4——如何选对深度学习模型?
本系列文章从机器学习基础出发,逐步深入至深度学习与Transformer模型,探讨AI关键技术原理及应用。内容涵盖模型架构解析、典型模型对比、预训练与微调策略,并结合Hugging Face平台进行实战演示,适合初学者与开发者系统学习AI核心知识。
248 15
|
1月前
|
XML Java Maven
@Bean`注解的使用方法及其作用
本文介绍了Spring框架中`@Bean`注解的使用方法及其作用,包括如何将第三方类库加入Spring容器,配置类与`@Configuration`的配合使用,以及通过`@ConditionalOnClass`、`@ConditionalOnMissingBean`等条件注解控制Bean的加载。同时讲解了Maven父子模块间的依赖关系及配置方式,帮助开发者更好地管理项目结构与依赖注入。