关闭

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

标签: java解迷宫问题回溯算法解迷宫问题回溯算法解迷宫java
4280人阅读 评论(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



2
0
查看评论

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

迷宫问题的JAVA编程求解
  • heipilxd
  • heipilxd
  • 2015-06-05 08:50
  • 3685

Java算法---华为oj迷宫问题求解(深度优先搜索)

自己花了好长时间学习了深度优先搜索算法,受益颇多,网上许多资料都看不太懂,最后自己按着那个思想一步一步实现了,分享一下,以华为oj上的迷宫问题为例来说一下: 问题描述: 定义一个二维数组N*M(其中2 int maze[5][5]={ 0, 1, 0, 0,&...
  • csdn_yaobo
  • csdn_yaobo
  • 2015-12-21 09:18
  • 2288

Java 递归算法解迷宫问题

上图是一个迷宫的图,0表示可以通过,1表示不可以通过,只能往上下左右走,左上角进去从右下角出去。 可以用一个二维数组来定义迷宫的初始状态,然后从左上角开始,不停的去试探所有可行的路线,碰到1就结束,然后继续探索其他的方向,为了防止在两个可行的格子之间来回走,我们需要标记一下已经走的路线。直到走到...
  • owenchan1987
  • owenchan1987
  • 2017-04-06 09:04
  • 1249

Java算法---华为oj迷宫问题求解(广度优先搜索)

一万年太久,只争朝夕,只有坚持,才能胜利,经过昨天的努力,解决了广度优先算法实现迷宫问题,题目在这里不赘述,如果不知道题目的请看我的上一篇博客Java算法---华为oj迷宫问题求解,这里面说的很详细,下来就直奔主题,说说广度优先搜索。        一般谈起广...
  • csdn_yaobo
  • csdn_yaobo
  • 2015-12-22 11:38
  • 1818

Java 迷宫问题,复杂多条件迷宫问题

回溯法是一种不断试探且及时纠正错误的搜索方法,下面的求解过程采用回溯法。从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达一个新点,否则试探下一个方向;若所有的方向均没有通路,则沿原路返回前一点,换下一个方向继续试探,直到所有可能的通路都搜索到,或找到一条通路,或无路可走又...
  • u011299745
  • u011299745
  • 2016-09-18 21:35
  • 1081

解迷宫问题的Java实现

问题: 有一个m行n列的迷宫,只有一个入口和一个出口,用0表示可以走,用1表示不可以走,现在编写一个程序列出所有可以走的路径。 迷宫示例: -1 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 2 0 0 (-1 表示入口,2表示出口) MazeCell类表示迷宫的一个位置: /*...
  • cuiods
  • cuiods
  • 2016-09-01 23:04
  • 1892

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

以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计程序,对任意设定的迷宫,求出从入口到出口的所有通路。     下面我们来详细讲一下迷宫问题的回溯算法。     该图是一个迷宫的图。1代表是墙不能走,0是可以走的路线。只能往上下...
  • tianyaleixiaowu
  • tianyaleixiaowu
  • 2016-03-21 17:16
  • 4280

(java)简单回朔法解决迷宫问题

import java.util.*; class Step{ int x,y,d; public Step(int x,int y,int d) { this.x = x;//横坐标 this.y = y;//纵坐标 this.d =...
  • chaiqunxing51
  • chaiqunxing51
  • 2016-09-28 20:32
  • 467

经典迷宫问题BFS

给定一个迷宫,入口为左上角,出口为右下角,问是否有路径从入口到出口,若有则输出一条这样的路径。注意移动可以从上、下、左、右、上左、上右、下左、下右八个方向进行。迷宫输入0表示可走,输入1表示墙。易得可以用1将迷宫围起来避免边界问题。 本题采用BFS算法给出解。注意,利用BFS算法给出的路径必然是一...
  • that163
  • that163
  • 2012-10-14 14:49
  • 23333

BFS求解迷宫问题初探(java版)

BFS,其英文全称是Breadth First Search。 BFS并不使用经验法则算法。从算法的观点,所有因为展开节点而得到的子节点都会被加进一个先进先出的队列中。一般的实验里,其邻居节点尚未被检验过的节点会被放置在一个被称为 open 的容器中(例如队列或是链表),而被检验过的节点则被放置在...
  • wuhengde
  • wuhengde
  • 2014-01-24 14:30
  • 2659
    个人资料
    • 访问:350043次
    • 积分:4389
    • 等级:
    • 排名:第8156名
    • 原创:100篇
    • 转载:39篇
    • 译文:0篇
    • 评论:148条
    博客专栏
    友情链接
    最新评论