如何使用递归跟踪(Java)找到特定迷宫的解决方案?

如何使用递归跟踪(Java)找到特定迷宫的解决方案?,java,recursion,recursive-backtracking,Java,Recursion,Recursive Backtracking,我正试图写一个递归求解迷宫的程序。完成步骤后,在迷宫中的该位置放置一个“x”字符并打印迷宫,如果迷宫到达死角,它将通过从该位置移除“x”来回溯其最后一个递归步骤 运行时,程序总是在第一步停止;它不能完全解决迷宫问题 我试过: -对每个连续步骤进行硬编码以避免迷宫中的障碍(但这会破坏使用递归的目的) -开始随机执行的第一步(但这会导致ArrayIndexOutOfBoundsException) import java.util.Random; 具有递归回溯的公共类MazeTraversal {

我正试图写一个递归求解迷宫的程序。完成步骤后,在迷宫中的该位置放置一个“x”字符并打印迷宫,如果迷宫到达死角,它将通过从该位置移除“x”来回溯其最后一个递归步骤

运行时,程序总是在第一步停止;它不能完全解决迷宫问题

我试过:

-对每个连续步骤进行硬编码以避免迷宫中的障碍(但这会破坏使用递归的目的)

-开始随机执行的第一步(但这会导致ArrayIndexOutOfBoundsException)

import java.util.Random;
具有递归回溯的公共类MazeTraversal
{
私有静态随机=新随机();
公共静态void main(字符串参数[])
{
char[][]迷宫={{{'.}、'.#'、'.#'、'.#'、'.#'、'.#'、'.#'、'.#'、'.#'、'.#'、'.#'、'.#'、'.#',
{'#', '.', '.', '.', '#', '.','.', '.', '.', '.', '.', '#'}, 
{'.', '.', '#', '.', '#', '.','#', '#', '#', '#', '.', '#'}, 
{'#', '#', '#', '.', '#', '.','.', '.', '.', '#', '.', '#'}, 
{'#', '.', '.', '.', '.', '#','#', '#', '.', '#', '.', '.'}, 
{'#', '#', '#', '#', '.', '#','.', '#', '.', '#', '.', '#'}, 
{'#', '.', '.', '#', '.', '#','.', '#', '.', '#', '.', '#'}, 
{'#', '#', '.', '#', '.', '#','.', '#', '.', '#', '.', '#'}, 
{'#', '.', '.', '.', '.', '.','.', '.', '.', '#', '.', '#'}, 
{'#', '#', '#', '#', '#', '#','.', '#', '#', '#', '.', '#'}, 
{'#', '.', '.', '.', '.', '.','.', '#', '.', '.', '.', '#'}, 
{'#', '#', '#', '#', '#', '#','#', '#', '#', '#', '#', '#'}};
印刷迷宫;
mazeTraversal(迷宫,2,0);
}
公共静态void mazeTraversal(char[][]迷宫,int currX,int currY)
{
int-choice=-1;
尝试
{
迷宫[咖喱][咖喱]='x';
印刷迷宫;
布尔选择=假;
如果((currX==4)和(&(currY==11))//迷宫结束
{
System.out.println(“迷宫完成”);
返回;
}
而(!选择)
{
选择=1;
//System.out.println(“选择”+选择);
如果(选项==0)
{
如果(迷宫[currX-1][currY]='.')//向上
{
System.out.println(“选择向上”);
选择=正确;
}
其他的
选择=随机。nextInt(4);
}
else if(选项==1)
{
如果(迷宫[currX][currY+1]='.')//正确
{
System.out.println(“选择权”);
选择=正确;
}
其他的
选择=随机。nextInt(4);
}
else if(选项==2)
{
如果(迷宫[currX+1][currY]='.')//向下
{
System.out.println(“选择向下”);
选择=正确;
}
其他的
选择=随机。nextInt(4);
}
else if(选项==3)
{
如果(迷宫[currX][currY-1]='.')//左
{
System.out.println(“选择左”);
选择=正确;
}
其他的
选择=随机。nextInt(4);
}
其他的
{
System.out.println(“尚未选择”);
选择=随机。nextInt(4);
}
//System.out.println(选项+“”+选项);
}
System.out.println(选项+“”+选项);
如果(选项==0)
mazeTraversal(迷宫,咖喱-1,咖喱);
else if(选项==1)
mazeTraversal(迷宫、咖喱、咖喱+1);
else if(选项==2)
mazeTraversal(迷宫,咖喱+1,咖喱);
else if(选项==3)
mazeTraversal(迷宫、咖喱、咖喱-1);
else//备份
{
递归回溯(迷宫、咖喱、咖喱);
}
}
捕获(阵列索引边界外异常)
{
例如printStackTrace();
System.out.println(“迷宫已完成选择=“+choice”);
}
}
公共静态void recursiveBacktrack(char[][]迷宫,int currX,int currY)
{
迷宫[咖喱][咖喱]='';
}
公共静态void打印迷宫(字符迷宫[])
{
对于(int i=0;i<12;++i)
{
对于(int j=0;j<12;++j)
{
系统输出打印(迷宫[i][j]+“”);
}
System.out.println();
}
System.out.println();
System.out.println();
}
}
预期结果:预期结果是通过在每个递归步骤后重新打印整个迷宫来递归求解迷宫,显示每次尝试。#是一堵墙,“.”是一个自由空间,“x”是一个已被占用的空间

实际结果:如前所述,我得到的实际结果只是程序无限循环的第一个递归步骤


错误消息:有时,我会收到错误消息ArrayIndexOutOfBoundsException:-1

首先让我们看看
isValidDirection
isSolution
应该如何工作:

public boolean isValidDirection(x, y) {
    return ((x < maze.length) &&
            (x >= 0) &&
            (y < maze[x].length) &&
            (y >= 0) &&
            (maxe[x][y] == '.'));
}

public boolean isSolution(x, y) {
    return isValidDirection(x, y) && (((x % maze.length) - 1 == 0) || ((y % maze[x].length) - 1 == 0));
}

当然,您需要确保所需的所有成员都已定义并正确初始化。

首先让我们看看
isValidDirection
isSolution
应该如何工作:

public boolean isValidDirection(x, y) {
    return ((x < maze.length) &&
            (x >= 0) &&
            (y < maze[x].length) &&
            (y >= 0) &&
            (maxe[x][y] == '.'));
}

public boolean isSolution(x, y) {
    return isValidDirection(x, y) && (((x % maze.length) - 1 == 0) || ((y % maze[x].length) - 1 == 0));
}

当然,您需要确保所需的所有成员都已定义并正确初始化。

您的选择=1必须在while循环之前,否则它总是等于1只是为了好玩我创建了自己的解算器:@Ehcnalb您是对的,它起作用了您的选择=1必须在while循环之前,否则它总是等于1只是为了好玩,我创建了自己的解算器:@Ehcnalb你是对的,它成功了
public boolean mazeRunner(x, y) {
    if (!isValidDirection) {
        //TODO: output the attempt
    }
    maze[x][y] = 'x';
    //add (x,y) to current attempt
    //we need to count attempt length 
    if (isSolution(x, y)) {
        //TODO: output the successful attempt
    } else if ((
        (mazeRunner(x - 1, y)) ||
        (mazeRunner(x + 1, y)) ||
        (mazeRunner(x, y - 1)) ||
        (mazeRunner(x, y + 1))
        ) == false) {
        //TODO: Output the current failed attempt
    }
    maze[x][y] = '.';
    //TODO: remove (x, y) from the current attempt
}

public void startMazeRunning(char[][] maze, x, y) {
    this.maze = maze;
}