回溯算法解迷宫问题(java版)

标签: java解迷宫问题 回溯算法解迷宫问题 回溯算法解迷宫java
4602人阅读 评论(1) 收藏 举报
分类:

    以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计程序,对任意设定的迷宫,求出从入口到出口的所有通路。

    下面我们来详细讲一下迷宫问题的回溯算法。

    该图是一个迷宫的图。1代表是墙不能走,0是可以走的路线。只能往上下左右走,直到从左上角到右下角出口。

    做法是用一个二维数组来定义迷宫的初始状态,然后从左上角开始,不停的去试探所有可行的路线,碰到1就结束本次路径,然后探索其他的方向,当然我们要标记一下已经走的路线,不能反复的在两个可行的格子之间来回走。直到走到出口为止,算找到了一个正确路径。

    程序如下,具体做法看注释即可。

package huisu;

/**
 * Created by wolf on 2016/3/21.
 */
public class MiGong {
    /**
     * 定义迷宫数组
     */
    private int[][] array = {
            {0, 0, 1, 0, 0, 0, 1, 0},
            {0, 0, 1, 0, 0, 0, 1, 0},
            {0, 0, 1, 0, 1, 1, 0, 1},
            {0, 1, 1, 1, 0, 0, 1, 0},
            {0, 0, 0, 1, 0, 0, 0, 0},
            {0, 1, 0, 0, 0, 1, 0, 1},
            {0, 1, 1, 1, 1, 0, 0, 1},
            {1, 1, 0, 0, 0, 1, 0, 1},
            {1, 1, 0, 0, 0, 0, 0, 0}

    };
    private int maxLine = 8;
    private int maxRow = 9;

    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis());
        new MiGong().check(0, 0);
        System.out.println(System.currentTimeMillis());
    }

    private void check(int i, int j) {
        //如果到达右下角出口
        if (i == maxRow - 1 && j == maxLine - 1) {
            print();
            return;
        }

        //向右走
        if (canMove(i, j, i, j + 1)) {
            array[i][j] = 5;
            check(i, j + 1);
            array[i][j] = 0;
        }
        //向左走
        if (canMove(i, j, i, j - 1)) {
            array[i][j] = 5;
            check(i, j - 1);
            array[i][j] = 0;
        }
        //向下走
        if (canMove(i, j, i + 1, j)) {
            array[i][j] = 5;
            check(i + 1, j);
            array[i][j] = 0;
        }
        //向上走
        if (canMove(i, j, i - 1, j)) {
            array[i][j] = 5;
            check(i - 1, j);
            array[i][j] = 0;
        }
    }

    private boolean canMove(int i, int j, int targetI, int targetJ) {
//        System.out.println("从第" + (i + 1) + "行第" + (j + 1) + "列,走到第" + (targetI + 1) + "行第" + (targetJ + 1) + "列");
        if (targetI < 0 || targetJ < 0 || targetI >= maxRow || targetJ >= maxLine) {
//            System.out.println("到达最左边或最右边,失败了");
            return false;
        }
        if (array[targetI][targetJ] == 1) {
//            System.out.println("目标是墙,失败了");
            return false;
        }
        //避免在两个空格间来回走
        if (array[targetI][targetJ] == 5) {
//            System.out.println("来回走,失败了");
            return false;
        }

        return true;
    }

    private void print() {
        System.out.println("得到一个解:");
        for (int i = 0; i < maxRow; i++) {
            for (int j = 0; j < maxLine; j++) {
                System.out.print(array[i][j] + " ");
            }
            System.out.println();
        }
    }
}
    我把打印每一步路径判断的地方注释掉了,放开注释就能看到所有走的路径。
    程序执行效率是非常快,基本上是在3ms之内得到所有路径。

    原本只看图时我还以为只有3条路径,没想到程序打出来了8条。后来仔细看看,果然是有8条路径……

    打印结果如下,5是用来标记路径的:

1458551044499
得到一个解:
5 5 1 0 0 0 1 0 
5 5 1 0 0 0 1 0 
5 0 1 0 1 1 0 1 
5 1 1 1 0 0 1 0 
5 5 5 1 5 5 5 0 
0 1 5 5 5 1 5 1 
0 1 1 1 1 0 5 1 
1 1 0 0 0 1 5 1 
1 1 0 0 0 0 5 0 
得到一个解:
5 5 1 0 0 0 1 0 
5 5 1 0 0 0 1 0 
5 0 1 0 1 1 0 1 
5 1 1 1 5 5 1 0 
5 5 5 1 5 5 5 0 
0 1 5 5 5 1 5 1 
0 1 1 1 1 0 5 1 
1 1 0 0 0 1 5 1 
1 1 0 0 0 0 5 0 
得到一个解:
5 5 1 0 0 0 1 0 
0 5 1 0 0 0 1 0 
5 5 1 0 1 1 0 1 
5 1 1 1 0 0 1 0 
5 5 5 1 5 5 5 0 
0 1 5 5 5 1 5 1 
0 1 1 1 1 0 5 1 
1 1 0 0 0 1 5 1 
1 1 0 0 0 0 5 0 
得到一个解:
5 5 1 0 0 0 1 0 
0 5 1 0 0 0 1 0 
5 5 1 0 1 1 0 1 
5 1 1 1 5 5 1 0 
5 5 5 1 5 5 5 0 
0 1 5 5 5 1 5 1 
0 1 1 1 1 0 5 1 
1 1 0 0 0 1 5 1 
1 1 0 0 0 0 5 0 
得到一个解:
5 0 1 0 0 0 1 0 
5 5 1 0 0 0 1 0 
5 5 1 0 1 1 0 1 
5 1 1 1 0 0 1 0 
5 5 5 1 5 5 5 0 
0 1 5 5 5 1 5 1 
0 1 1 1 1 0 5 1 
1 1 0 0 0 1 5 1 
1 1 0 0 0 0 5 0 
得到一个解:
5 0 1 0 0 0 1 0 
5 5 1 0 0 0 1 0 
5 5 1 0 1 1 0 1 
5 1 1 1 5 5 1 0 
5 5 5 1 5 5 5 0 
0 1 5 5 5 1 5 1 
0 1 1 1 1 0 5 1 
1 1 0 0 0 1 5 1 
1 1 0 0 0 0 5 0 
得到一个解:
5 0 1 0 0 0 1 0 
5 0 1 0 0 0 1 0 
5 0 1 0 1 1 0 1 
5 1 1 1 0 0 1 0 
5 5 5 1 5 5 5 0 
0 1 5 5 5 1 5 1 
0 1 1 1 1 0 5 1 
1 1 0 0 0 1 5 1 
1 1 0 0 0 0 5 0 
得到一个解:
5 0 1 0 0 0 1 0 
5 0 1 0 0 0 1 0 
5 0 1 0 1 1 0 1 
5 1 1 1 5 5 1 0 
5 5 5 1 5 5 5 0 
0 1 5 5 5 1 5 1 
0 1 1 1 1 0 5 1 
1 1 0 0 0 1 5 1 
1 1 0 0 0 0 5 0 
1458551044503



查看评论

机器学习-Q-Learning-沙鼠走迷宫

-
  • 1970年01月01日 08:00

迷宫问题(MazePath)的求解——利用回溯法(backtracking)

迷宫问题(MazePath)的求解——利用回溯法(backtracking) 1. 迷宫问题的提法 迷宫问题是典型的图的搜索问题。 假设一个迷宫,只有一个入口和一个出口。如果从迷宫的入口到达出口,...
  • cainv89
  • cainv89
  • 2016-05-25 23:07:51
  • 7611

迷宫问题算法设计与实现

迷宫问题算法的实现(基于队列版本和回朔法版本)
  • u011889952
  • u011889952
  • 2015-04-01 13:01:20
  • 16077

回溯法解决迷宫问题

迷宫问题,是一个非常经典的问题,我们通过栈这种数据结构来解决这个问题。1.设计思路我们这里采用回溯法解决迷宫问题,即从入口出发,顺某一方向试探,若能走通,则继续往前走,否则原路返回,换另一个方向继续试...
  • qq_26768741
  • qq_26768741
  • 2016-09-10 13:16:35
  • 3578

迷宫问题两种算法

 1)问题描述:给定一个M*N的迷宫图,求一条从指定入口到出口的路径。假设迷宫用下图表示。对于每一个方块空白表示通道,阴影表示墙。所求路径必须是简单路径,即在求得的路径上不能重复出现同一个通道块。2)...
  • gudujianjsk
  • gudujianjsk
  • 2010-04-02 15:38:00
  • 2769

迷宫问题(maze problem)——深度优先(DFS)与广度优先搜索(BFS)求解

1.问题简介给定一个迷宫,指明起点和终点,找出从起点出发到终点的有效可行路径,就是迷宫问题(maze problem)。迷宫可以以二维数组来存储表示。0表示通路,1表示障碍。注意这里规定移动可以从上、...
  • K346K346
  • K346K346
  • 2016-05-02 11:27:34
  • 18218

迷宫问题——回溯法解

题目描述    迷宫是一个二维矩阵,其中1为墙,0为路,入口在第一列,出口在最后一列。     要求从入口开始,从出口结束,按照 上,下,左,右 的顺序来搜索路径...
  • zhuofeilong
  • zhuofeilong
  • 2015-08-31 10:53:14
  • 5401

回溯法求解迷宫问题

利用回溯法求解迷宫问题大致可以这样理解: 1.确定迷宫大小,确定迷宫格可走阻塞已走过的标志,确定入口出口; 2.想清楚如何走,如何找到出口(走到每一个格子都考虑其上下左右相邻能否走通,根据格子状态...
  • return_cc
  • return_cc
  • 2017-07-24 13:33:37
  • 180

回溯算法求解迷宫问题

  • 2013年12月26日 15:24
  • 68KB
  • 下载

算法编程(JAVA)--迷宫问题

迷宫问题的JAVA编程求解
  • heipilxd
  • heipilxd
  • 2015-06-05 08:50:11
  • 4326
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 46万+
    积分: 5575
    排名: 5953
    博客专栏
    友情链接
    最新评论