Java 给定迷宫中自始至终的路径数

Java 给定迷宫中自始至终的路径数,java,algorithm,depth-first-search,Java,Algorithm,Depth First Search,所以我试图找出在一个给定的迷宫中自始至终存在着多少种方式 这是我的代码,使用深度优先搜索 import java.util.Stack; public class NumberofWaysInAMaze { class VisitedNode { private int x; private int y; public VisitedNode(int x, int y) { this.x = x; this.y = y;

所以我试图找出在一个给定的迷宫中自始至终存在着多少种方式

这是我的代码,使用深度优先搜索

import java.util.Stack;

public class NumberofWaysInAMaze {
class VisitedNode
{
    private int x;
    private int y;


    public VisitedNode(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

public int findNumberofWaysToMaze(boolean[][] maze, int targetX, int targetY)
{
    int numberofWays = 0;
    int rows = maze.length;
    int columns = maze[0].length;
    boolean[][] visitedMap = new boolean[rows][columns];
    for(int i=0; i < rows; i++)
    {
        System.arraycopy(maze[i], 0, visitedMap[i], 0, maze[i].length);
    }

    Stack<VisitedNode> stack = new Stack<VisitedNode>();

    VisitedNode root = new VisitedNode(0, 0);
    stack.push(root);

    while(!stack.empty())
    {
        VisitedNode visitingNode = stack.pop();
        int currentX = visitingNode.x;
        int currentY = visitingNode.y;
        if(currentX == targetX && currentY == targetY)
        {
            numberofWays++;
        }else

        {//System.out.println("x is:" + currentX + "--- y is:" + currentY);
        visitedMap[currentX][currentY] = true;
        }
        if(currentX+1 <= targetX && currentX+1 >= 0 && visitedMap[currentX+1][currentY] == false && maze[currentX+1][currentY] == false)
        {
            stack.push(new VisitedNode(currentX+1, currentY));
        }

        if(currentX-1 <= targetX && currentX-1 >= 0 && visitedMap[currentX-1][currentY] == false && maze[currentX-1][currentY] == false)
        {
            stack.push(new VisitedNode(currentX-1, currentY));
        }

        if(currentY+1 <= targetY && currentY+1 >= 0 && visitedMap[currentX][currentY+1] == false && maze[currentX][currentY+1] == false)
        {
            stack.push(new VisitedNode(currentX, currentY+1));
        }

        if(currentY-1 <= targetY && currentY-1 >= 0 && visitedMap[currentX][currentY-1] == false && maze[currentX][currentY-1] == false)
        {
            stack.push(new VisitedNode(currentX, currentY-1));
        }

    }

    return numberofWays;
}

public static void main(String[] args)
{
    NumberofWaysInAMaze test = new NumberofWaysInAMaze();
    boolean[][] maze = 
            {
             {false, false, false, false, false},
             {false, true, false, true, false},
             {false, true, false, true, false},
             {false, true, false, true, false},
             {false, false, false, false, false},
            };
    System.out.println(test.findNumberofWaysToMaze(maze, 4, 4));
}
import java.util.Stack;
公共类号Waysinaze{
类VisitedNode
{
私人INTX;
私营企业;
公共访问节点(整数x,整数y)
{
这个.x=x;
这个。y=y;
}
}
public int findnumberOfWaymosize(布尔[][]迷宫,int targetX,int targetY)
{
int numberofWays=0;
int rows=maze.length;
int columns=maze[0]。长度;
boolean[][]visitedMap=新的boolean[行][列];
对于(int i=0;i
}

然而,结果并不正确。我的输出是2,显然,在给定的迷宫中有四种方式(false表示可以通过,true表示阻塞)。我知道原因是因为我使用另一个2D数组来记录是否访问了某个点。但是,我不知道如何修改我的解决方案。如有任何意见或建议,将不胜感激


谢谢

您正确地假设您的
访问地图
导致了问题。问题是多条路径可以通过同一个节点,因此得到的结果是2,因为只有两个可能的位置紧邻目标

不幸的是,您实现的堆栈无法将访问点的路径解回到添加每个位置时可用的路径

这将更容易让您递归地实现。当您进入该功能时,将
(currentX,currentY)
处的点标记为已访问。当您离开函数时,您将取消标记它。这将正确地解开您的路径

您的函数如下所示:

public int findNumberofWaysToMaze( boolean[][] maze, boolean[][] visitedMap,
                                   int currentX, int currentY, int targetX, int targetY )
{
    if( currentX == targetX && currentY == targetY ) return 1;

    if( currentX < 0 || currentX >= maze.length ) return 0;            // X out of bounds
    if( currentY < 0 || currentY >= maze[currentX].length ) return 0;  // Y out of bounds
    if( visitedMap[currentX][currentY] == true ) return 0;             // Already seen
    if( maze[currentX][currentY] == true ) return 0;                   // Wall

    visitedMap[currentX][currentY] = true;

    int numberofWays = 0;
    numberofWays += findNumberofWaysToMaze(maze, visitedMap, currentX-1, currentY, targetX, targetY );
    numberofWays += findNumberofWaysToMaze(maze, visitedMap, currentX+1, currentY, targetX, targetY );
    numberofWays += findNumberofWaysToMaze(maze, visitedMap, currentX, currentY-1, targetX, targetY );
    numberofWays += findNumberofWaysToMaze(maze, visitedMap, currentX, currentY+1, targetX, targetY );

    visitedMap[currentX][currentY] = false;
    return numberofWays;
}
public int findnumberOfWaytosize(布尔[]]maze,布尔[]]visitedMap,
int currentX,int currentY,int targetX,int targetY)
{
如果(currentX==targetX&¤tY==targetY)返回1;
如果(currentX<0 | | currentX>=maze.length)返回0;//X超出范围
if(currentY<0 | | currentY>=maze[currentX].length)返回0;//Y超出范围
if(visitedMap[currentX][currentY]==true)返回0;//已看到
如果(maze[currentX][currentY]==true)返回0;//墙
visitedMap[currentX][currentY]=真;
int numberofWays=0;
NumberOfWayToze+=FindNumberOfWayToze(迷宫、访问地图、currentX-1、currentY、targetX、targetY);
NumberOfWayToze+=FindNumberOfWayToze(迷宫、访问地图、currentX+1、currentY、targetX、targetY);
NumberOfWayToze+=FindNumberOfWayToze(迷宫、访问地图、currentX、currentY-1、targetX、targetY);
NumberOfWayToze+=FindNumberOfWayToze(迷宫、访问地图、currentX、currentY+1、targetX、targetY);
visitedMap[currentX][currentY]=假;
返回路径数;
}

当然,您可以将其设置为私有的,并将原始路径用作基本包装(创建并初始化
visitedMap
)。

这四条路径是什么?我看到五个(所以我一定弄错了)。@acdcjunior头朝右,头朝右取中间,头朝下,头朝下取中间。这是四个。@KingSaber你需要重写
FindNumberOfWaytomize
,使其递归而不是迭代,在每个交叉点进行分支,在遇到死胡同或找到路径时递归回溯,等等。入口/出口在哪里?@Patashu,是的,谢谢,这就是我的想法。我想我数得太快了,走了两次路。谢谢,这真是太好了!顺便说一句,我有办法使这个非递归吗?哎呀,我忘了添加墙测试。是的,你可以使它非递归,但你必须以某种方式将“访问”放在堆栈上。递归方法会自动执行此操作,因为递归已经是一个堆栈。我想不出确切的方法来描述它,这就是为什么我建议使用递归更容易实现的原因。