回溯算法之迷宫问题

  • 前言
  • 算法思路
  • 一、回溯算法
  • 二、经典问题之迷宫问题(Maze)
    • (一)问题阐述
    • (二)解题思路
    • (三)算法代码(java)
      • 结果图

前言

    迷宫问题是回溯算法的经典问题,其中的思路方法很重要。

算法思路

一、回溯算法

    回溯算法实际上是一个类似枚举的搜索尝试过程,主要是在搜素尝试过程中寻找问题的解,当发现已满足求解条件时,就“回溯”返回,尝试别的路径。
    回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标,但当搜索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种不通就回退再走的技术称为回溯法,而满足回溯条件的某个状态的点称为“回溯”点,许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。
    从一条路往前走,能进则进,不能进则退回来,换一条路再试。

二、经典问题之迷宫问题(Maze)

    单迷宫是只有一种走法的迷宫。对于单迷宫而言,有一种万能的破解方法,即沿着某一面墙壁走。在走的时候,左(右)手一直摸着左(右)边的墙壁,这种方法可能费时最长,也可能会使你走遍迷宫的每一个角落和每一条死路,但玩者绝不会永远困在里面。

(一)问题阐述

    迷宫问题:当从一个入口进入时,会遇到很多墙,在走的过程中如果遇到墙就要返回上一个位置,看上一个位置是否有其他方向的路可以走,依次循环进行,直到找到出口位置。迷宫有很多墙,阻挡住迷宫的路无法进行下去,所以需要在可行走的路中,找到最优达到出口的路。
    可以先遍历所有可能出去的路,如果遇到墙,标记下来,以免下次重复遍历。
    首先每次进入只能走一步;
    将走过的路进行标记,表示已经走过;
    若遇到墙的话,需要退到上一步,判断是否还有其他方向的路可以走。
下图为迷宫图(仅供参考):

(二)解题思路

    首先可以将迷宫用二维数组来表示:1代表该位置不可达(就是墙),0代表该位置可达(就是路),如下图所示,把出口和入口表示出来。(即入口坐标为maze[1][0],出口坐标为maze[7][8])

    然后从入口开始先标记,把每次走的路的坐标先标记下来,防止会重复走同一条路;再去判断每走一步是否可以通,从上右下左四个方向来判断,这里可以将四个方向表示为二维数组,向上走的话就是给y轴-1,向右走就是给x轴+1,向下走就给y轴+1,向左走就是给x轴-1,即int[][] direction = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};给所在坐标x和y值加二维数组得值就可以改变方向。

    如果所在坐标有其他方向的路可以走,然后判断其他方向的坐标是否在整个迷宫的矩阵范围内,是否是可以走的路,是否已经走过,如果都满足就可以继续向下走;如果遇到走不通的路,就需要消掉。
    本文中所说的迷宫是一种简单的迷宫,只是提供一种解迷宫问题的思想,要是遇到比较难或者复杂的迷宫问题,可以基于此思想上进行加工。

(三)算法代码(java)

package part05.分治回溯;import part02.动态链表.LinkedList;//迷宫
public class Maze {//定义始点private static int enterX = 1;private static int enterY = 0;//定义终点private static int exitX = 7;private static int exitY = 8;//创建一个存放坐标的栈private static LinkedList<String> stack = new LinkedList<>();//定义一个表示坐标已走过的数组private static boolean[][] vistied = new boolean[9][9];//定义一个方向数组 上右下左private static int[][] direction = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};private static int[][] maze = {{1, 1, 1, 1, 1, 1, 1, 1, 1},{0, 0, 1, 0, 0, 0, 1, 1, 1},{1, 0, 1, 1, 1, 0, 1, 1, 1},{1, 0, 0, 1, 0, 0, 1, 1, 1},{1, 1, 0, 1, 1, 0, 0, 0, 1},{1, 0, 0, 0, 0, 0, 1, 0, 1},{1, 0, 1, 1, 1, 0, 0, 0, 1},{1, 1, 0, 0, 0, 0, 1, 0, 0},{1, 1, 1, 1, 1, 1, 1, 1, 1}};public static void main(String[] args) {if (go(enterX,enterY)) {//求解迷宫的解,如果可以走通返回trueSystem.out.println("能走通!");//打印能走通的路线while (!stack.isEmpty()) {//前提是不为空System.out.print(stack.poll());//把所有的栈里面的元素出队}} else {System.out.println("不能走通!");}}//递归求解迷宫的解,以当前的x,y向下寻找终点private static boolean go(int x, int y) {stack.push("(" + x + "," + y + ")");//先将坐标进栈vistied[x][y] = true;//标记进栈的点已走过//如果走到终点的话就返回,向上级汇报,可以走通(回溯)if (x == exitX && y == exitY) {return true;}//向四个方向遍历for (int i = 0; i < direction.length; i++) {//这里是循环四个方向,如果一个方向不通,遍历找四个方向,若一个方向通就可以继续走,若都不通就是且已经回溯完就是都不通/** direction = {* {-1, 0},* {0, 1},* {1, 0},* {0, -1}}* *///direction数组是二维数组,里面每个是一维数组,0,0指的是二维数组的第一行,一维数组里面的第一列int newX = x + direction[i][0];int newY = y + direction[i][1];//if (isInArea(newX, newY) && isRoad(newX, newY) && !vistied[newX][newY]) {//如果坐标满足在给的9*9矩阵区域里,且在路上,并且没有走过,则继续向下走if (go(newX, newY)) {//这里是如果可以走下去,一直调用,可以走下去就返回true(递归)return true;//(回溯)}}}stack.pop();//如果不满足,走不下去,则出栈return false;}//坐标在路上private static boolean isRoad(int x, int y) {return maze[x][y] == 0;//0位置表示是路}//坐标在区域内private static boolean isInArea(int x, int y) {return x >= 0 && x < 9 && y >= 0 && y < 9;}
}

    注意:此代码中用到的LinkedList类是自己所写的结构,相应的代码中用到就是其中所写的方法,但是本意基本不变,只要有队列和栈的基本的入栈,出栈,入队,出队等一些基本方法即可,用jdk中自带的方法就可以。

结果图


回溯算法之迷宫问题(Maze)相关推荐

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

    目录 1.走迷宫与回溯算法 2.迷宫设计栈扮演的角色 3.Python实现走迷宫 栈的应用有许多,本篇博文着重将栈与回溯(Backtracking)算法结合,设计走迷宫程序.其实回溯算法也是人工智能的 ...

  2. 回溯算法解决迷宫问题

    文章目录 前言 一.回溯法 二.算法应用--迷宫问题 1.问题描述 2.解题思路 三.Java代码实现 前言 本文介绍一种经典算法--回溯法,可作为迷宫问题的一种解法. 一.回溯法 回溯是一种算法思想 ...

  3. java 回溯_java 实现迷宫回溯算法示例详解

    用一个7 x 7的矩形表示迷宫,0和1分别表示的是通路和障碍.通过设计编写程序找到蓝色小球达到蓝色旗子的路线 思路: 构建一个迷宫(用二维数组)实现找通路的方法findRoad() 构建二维数组不难, ...

  4. 基本算法-回溯法(迷宫问题)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 前言 本文介绍一种经典算法--回溯法,可作为迷宫问题的一种解法,以下是本篇文章正文内容,包括算法 ...

  5. 回溯算法经典问题-迷宫问题

    迷宫问题是一道经典的回溯算法问题,给定一个迷宫矩阵,矩阵中的1表示障碍,0表示可走通路,给定迷宫入口出口,要求寻找从入口穿过迷宫到达出口的所有路径,有则输出,无则给出提示.一本合格的数据结构教科书一般 ...

  6. JAVA算法:走迷宫回溯算法设计(JAVA版本)

    JAVA算法:走迷宫回溯算法设计(JAVA版本) 迷宫数组 int[][] maze = {                 {0, 1, 0, 0, 0},                 {0, ...

  7. 迷宫之深搜回溯算法(B站)

    迷宫之深搜回溯算法 题目描述 核心思路 用char Map0[9][9][9][9][9][9]来存储题目给定的地图,由于是它的数组下标是从0开始的,但是我们想把点的坐标从1开始,所以我们可以对原地图 ...

  8. c++矩阵连乘的动态规划算法并输出_「Javascript算法设计」× 动态规划与回溯算法...

    目录: 分而治之算法 动态规划 回溯算法 分而治之算法 分而治之算法是算法设计的一种方式,它将一个问题分成多个和原问题相似的小问题,递归解决小问题,再将解决方式合并以解决原来的问题(例如快速排序,二分 ...

  9. 实验三:基于A*算法的迷宫

    实验要求: 1.迷宫随机生成 2.玩家走迷宫,留下足迹: 3.系统用A*算法寻路,输出路径 解决问题: 1.如何显示迷宫的图形界面: 2.如何生成随机的迷宫: 3.怎样移动游戏中走迷宫的"玩 ...

  10. 理解回溯算法——回溯算法的初学者指南

    0 前言 最近做了不少关于回溯法的算法题,积累了一些心得,这篇博文算是对回溯法的一个小总结. 1 回溯法简介 回溯法简单来说就是按照深度优先的顺序,穷举所有可能性的算法,但是回溯算法比暴力穷举法更高明 ...

最新文章

  1. gitlab使用_如何在正确使用 Docker 搭建 GitLab
  2. ipv6host更新
  3. Java JDBC数据库 之 DBUtil 封装类
  4. 【Nginx】错误: [emerg] “proxy_pass“ cannot have URI part in location given by regular expression,...
  5. oracle函数lp,Oracle 执行计划的查看方式
  6. oracle 10g 报错:ORA-00257: archiver error. Connect internal only, until freed
  7. kali linux查看网卡_CentOS7.6安装无线网卡驱动|Linux如何安装网卡驱动|Linux如何让配置网卡...
  8. Navicat Premium 实用快捷键
  9. [python]---从java到python(02)---多线程,队列
  10. 迷你世界显示未连接服务器成功,迷你世界登录未成功是什么意思 | 手游网游页游攻略大全...
  11. MBSA有关安全漏洞的检查说明一
  12. python元祖切片_Python
  13. windows下ulipad开发环境安装
  14. 电子设计(1)二极管防电源反接电路
  15. OpenVINO之链接库
  16. python中次方怎么表示_python中n次方怎么表示
  17. 刷题记录:牛客NC16122郊区春游
  18. SiC碳化硅二极管抗浪涌电流能力缺点及应对方式
  19. 输入某年某月某日,判断这一天是这一年的第几天?考虑闰年的情况
  20. 动物实验可用计算机模拟,《动物实验类试题》.doc

热门文章

  1. php 减号,PHP编码转换减号(连接符)无法转换问题
  2. 读书笔记 大前研一 《M型社会》
  3. 我国计算机发展的四个阶段,计算机发展历程.ppt
  4. sql数据库去重语法_SQL如何去重?
  5. 主流无线芯片厂商的自动信道选择算法小结
  6. php读取本地txt,php读取本地文件常用函数(fopen与file_get_contents)_PHP教程
  7. R语言|plot和par函数绘图详解,绘图区域设置 颜色设置 绘图后修改及图像输出
  8. Arrays.sort(arr, (a, b) -> a - b)是对数组进行排序
  9. 射影几何----坎迪定理的证明
  10. 金蝶云星空二次开发-数据库存查询