java实现迷宫算法--转

简介:

沿着所有方向进行探测,有路径则走,没有路径则从栈中回退。

回溯法是一种不断试探且及时纠正错误的搜索方法,下面的求解过程采用回溯法。从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达一个新点,否则试探下一个方向;若所有的方向均没有通路,则沿原路返回前一点,换下一个方向继续试探,直到所有可能的通路都搜索到,或找到一条通路,或无路可走又返回到入口点。这里可以用一个栈来实现,每走一步,将该位置压入栈中,若该点无路可走,则出栈返回上一位置。
需要解决的四个问题:
(1)表示迷宫的数据结构
设迷宫为m行n列,利用数组maze[m][n]来表示一个迷宫,maze[i][j]=0或1,其中0表示通路,1表示不通。迷宫该数组四边都为1,代表迷宫四周都是墙。这样就可以保证每个点都有8个方向可以试探。
入口为(1,1),出口为(6,8)
1,1,1,1,1,1,1,1,1,1
1,0,1,1,1,0,1,1,1,1
1,1,0,1,0,1,1,1,1,1
1,0,1,0,0,0,0,0,1,1
1,0,1,1,1,0,1,1,1,1
1,1,0,0,1,1,0,0,0,1
1,0,1,1,0,0,1,1,0,1
1,1,1,1,1,1,1,1,1,1
(2)试探方向
迷宫中间每个点都有8个方向可以试探。其增量数组可以用一个8*2的二维数组move表述,表示对当前点而言,它周围8个点的行和列的坐标偏移量.具体值如下:
x  y
0  1
1 1
1 0
1 -1
0 -1
-1 -1
-1 0
-1 1
在move数组中,x表示横坐标的增量,y表示纵坐标的增量。
(3)栈中存放元素的设计
栈中所存放的元素应该包含所到达的每点的坐标以及从该点沿哪个方向向下走的,可用一个类表示:
class Step{
int x,y,d;
public Step(int x,int y,int d) {
this.x = x;//横坐标
this.y = y;//纵坐标
this.d = d;//方向
}
}
(4)防止重复到达某点而发生死循环
使maze[i][j]置为-1,以便区别为达到的点,同样也可以防止走重复点的作用。

复制代码
源码如下:
package com.test;

import java.util.Stack;
class Step{
    int x,y,d;
    public Step(int x,int y,int d) {
        this.x = x;//横坐标
        this.y = y;//纵坐标
        this.d = d;//方向
}
}

public class MazeTest {

public static void main(String[] args) {
// 迷宫定义
int[][] maze = {{1,1,1,1,1,1,1,1,1,1},
    {1,0,1,1,1,0,1,1,1,1},
    {1,1,0,1,0,1,1,1,1,1},
    {1,0,1,0,0,0,0,0,1,1},
    {1,0,1,1,1,0,1,1,1,1},
    {1,1,0,0,1,1,0,0,0,1},
    {1,0,1,1,0,0,1,1,0,1},
    {1,1,1,1,1,1,1,1,1,1}};
int[][] move = {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
    Stack s = new Stack();
    Stack s1 = new Stack();
    int a = path(maze, move, s);
    while(!s.isEmpty()){
    Step step = s.pop();
    System.out.println(step.x+":"+step.y);
    }
}
public static int path(int[][] maze,int[][] move,Stack s){
    Step temp = new Step(1,1,-1); //起点
    s.push(temp);
    while(!s.isEmpty()){
        temp = s.pop();
        int x = temp.x;
        int y = temp.y;
        int d = temp.d+1;
    while(d<8){
        int i = x + move[d][0];
        int j = y + move[d][1];
        if(maze[i][j] == 0){ //该点可达
        temp = new Step(i,j,d); //到达新点
        s.push(temp);
        x = i;
        y = j;
    maze[x][y] = -1; //到达新点,标志已经到达
    if(x == 6 && y == 8){
        return 1; //到达出口,迷宫有路,返回1
    }else{
        d = 0; //重新初始化方向
    }
}else{
    d++; //改变方向
    }
    }
}
    return 0;
}

}                            
复制代码

代码2:

复制代码
import java.util.*;
 
class Position{
    public Position(){
 
    }
 
    public Position(int row, int col){
        this.col = col;
        this.row = row;
    }
 
    public String toString(){
        return "(" + row + " ," + col + ")";
    }
 
    int row;
    int col;
}
 
class Maze{
    public Maze(){
        maze = new int[15][15];
        stack = new Stack<Position>();
        p = new boolean[15][15];
    }
 
    /*
     * 构造迷宫
     */
    public void init(){
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入迷宫的行数");
        row = scanner.nextInt();
        System.out.println("请输入迷宫的列数");
        col = scanner.nextInt();
        System.out.println("请输入" + row + "" + col + "列的迷宫");
        int temp = 0;
        for(int i = 0; i < row; ++i) {
            for(int j = 0; j < col; ++j) {
                temp = scanner.nextInt();
                maze[i][j] = temp;
                p[i][j] = false;
            }
        }
    }
 
    /*
     * 回溯迷宫,查看是否有出路
     */
    public void findPath(){
        // 给原始迷宫的周围家一圈围墙
        int temp[][] = new int[row + 2][col + 2];
        for(int i = 0; i < row + 2; ++i) {
            for(int j = 0; j < col + 2; ++j) {
                temp[0][j] = 1;
                temp[row + 1][j] = 1;
                temp[i][0] = temp[i][col + 1] = 1;
            }
        }
        // 将原始迷宫复制到新的迷宫中
        for(int i = 0; i < row; ++i) {
            for(int j = 0; j < col; ++j) {
                temp[i + 1][j + 1] = maze[i][j];
            }
        }
        // 从左上角开始按照顺时针开始查询
 
        int i = 1;
        int j = 1;
        p[i][j] = true;
        stack.push(new Position(i, j));
        while (!stack.empty() && (!(i == (row) && (j == col)))) {
 
            if ((temp[i][j + 1] == 0) && (p[i][j + 1] == false)) {
                p[i][j + 1] = true;
                stack.push(new Position(i, j + 1));
                j++;
            } else if ((temp[i + 1][j] == 0) && (p[i + 1][j] == false)) {
                p[i + 1][j] = true;
                stack.push(new Position(i + 1, j));
                i++;
            } else if ((temp[i][j - 1] == 0) && (p[i][j - 1] == false)) {
                p[i][j - 1] = true;
                stack.push(new Position(i, j - 1));
                j--;
            } else if ((temp[i - 1][j] == 0) && (p[i - 1][j] == false)) {
                p[i - 1][j] = true;
                stack.push(new Position(i - 1, j));
                i--;
            } else {
                stack.pop();
                if(stack.empty()){
                    break;
                }
                i = stack.peek().row;
                j = stack.peek().col;
            }
 
        }
 
        Stack<Position> newPos = new Stack<Position>();
        if (stack.empty()) {
            System.out.println("没有路径");
        } else {
            System.out.println("有路径");
            System.out.println("路径如下:");
            while (!stack.empty()) {
                Position pos = new Position();
                pos = stack.pop();
                newPos.push(pos);
            }
        }
         
        /*
         * 图形化输出路径
         * */
         
        String resault[][]=new String[row+1][col+1];
        for(int k=0;k<row;++k){
            for(int t=0;t<col;++t){
                resault[k][t]=(maze[k][t])+"";
            }
        }
        while (!newPos.empty()) {
            Position p1=newPos.pop();
            resault[p1.row-1][p1.col-1]="#";
         
        }
         
        for(int k=0;k<row;++k){
            for(int t=0;t<col;++t){
                System.out.print(resault[k][t]+"\t");
            }
            System.out.println();
        }
     
 
    }
 
    int maze[][];
    private int row = 9;
    private int col = 8;
    Stack<Position> stack;
    boolean p[][] = null;
}
 
class hello{
    public static void main(String[] args){
        Maze demo = new Maze();
        demo.init();
        demo.findPath();
    }
}
复制代码

 


本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/4479563.html,如需转载请自行联系原作者

相关文章
|
8月前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
2268 35
|
8月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
8月前
|
存储 算法 搜索推荐
《数据之美》:Java数据结构与算法精要
本系列深入探讨数据结构与算法的核心原理及Java实现,涵盖线性与非线性结构、常用算法分类、复杂度分析及集合框架应用,助你提升程序效率,掌握编程底层逻辑。
|
10月前
|
运维 监控 算法
基于 Java 滑动窗口算法的局域网内部监控软件流量异常检测技术研究
本文探讨了滑动窗口算法在局域网流量监控中的应用,分析其在实时性、资源控制和多维分析等方面的优势,并提出优化策略,结合Java编程实现高效流量异常检测。
419 0
|
11月前
|
机器学习/深度学习 算法 Java
Java实现林火蔓延路径算法
记录正在进行的森林防火项目中林火蔓延功能,本篇文章可以较好的实现森林防火蔓延,但还存在很多不足,如:很多参数只能使用默认值,所以蔓延范围仅供参考。(如果底层设备获取的数据充足,那当我没说)。注:因林火蔓延涉及因素太多,如静可燃物载量、矿质阻尼系数等存在估值,所以得出的结果仅供参考。
515 5
|
11月前
|
存储 监控 算法
企业上网监控场景下布隆过滤器的 Java 算法构建及其性能优化研究
布隆过滤器是一种高效的数据结构,广泛应用于企业上网监控系统中,用于快速判断员工访问的网址是否为违规站点。相比传统哈希表,它具有更低的内存占用和更快的查询速度,支持实时拦截、动态更新和资源压缩,有效提升系统性能并降低成本。
525 0
|
11月前
|
存储 负载均衡 算法
我们来说一说 Java 的一致性 Hash 算法
我是小假 期待与你的下一次相遇 ~
625 1
|
存储 算法 安全
Java中的对称加密算法的原理与实现
本文详细解析了Java中三种常用对称加密算法(AES、DES、3DES)的实现原理及应用。对称加密使用相同密钥进行加解密,适合数据安全传输与存储。AES作为现代标准,支持128/192/256位密钥,安全性高;DES采用56位密钥,现已不够安全;3DES通过三重加密增强安全性,但性能较低。文章提供了各算法的具体Java代码示例,便于快速上手实现加密解密操作,帮助用户根据需求选择合适的加密方案保护数据安全。
859 58
|
机器学习/深度学习 算法 数据可视化
基于Qlearning强化学习的机器人迷宫路线搜索算法matlab仿真
本内容展示了基于Q-learning算法的机器人迷宫路径搜索仿真及其实现过程。通过Matlab2022a进行仿真,结果以图形形式呈现,无水印(附图1-4)。算法理论部分介绍了Q-learning的核心概念,包括智能体、环境、状态、动作和奖励,以及Q表的构建与更新方法。具体实现中,将迷宫抽象为二维网格世界,定义起点和终点,利用Q-learning训练机器人找到最优路径。核心程序代码实现了多轮训练、累计奖励值与Q值的可视化,并展示了机器人从起点到终点的路径规划过程。
666 0
|
人工智能 算法 NoSQL
LRU算法的Java实现
LRU(Least Recently Used)算法用于淘汰最近最少使用的数据,常应用于内存管理策略中。在Redis中,通过`maxmemory-policy`配置实现不同淘汰策略,如`allkeys-lru`和`volatile-lru`等,采用采样方式近似LRU以优化性能。Java中可通过`LinkedHashMap`轻松实现LRUCache,利用其`accessOrder`特性和`removeEldestEntry`方法完成缓存淘汰逻辑,代码简洁高效。
585 0