即使找到路径,BFS 迷宫求解器也会返回 false

时间:2021-01-04 17:55:47

标签: java algorithm loops breadth-first-search maze

我目前正在开发一个小型迷宫求解器项目,您可以在其中找到迷宫中的最短路径,以便更好地掌握路径搜索算法;在这种情况下,广度优先搜索算法。它的工作原理是使用布尔访问矩阵来标记访问过的单元格以避免重复步骤,它的工作步骤如下。

第一步:使用访问队列来保存相邻的单元格。

第 2 步:移除队列前面的单元格并将其添加到访问列表中。

第 3 步:检查相邻的单元格,如果它们不是墙且未被访问,则将它们添加到访问队列中。

然后重复最后两步,直到整个队列为空。

然而,我的迷宫求解器奇怪地一直返回 false,即使它已经找到了最后的方法(即数字 3)。总而言之,我有两个问题,是什么导致它即使找到了也返回 false 以及可以在求解器中更改什么,以便只有最短路径的数字为 2(即当它回溯时它会将死胡同变回 0)?

提前致谢!

BFS 迷宫求解器

import java.util.LinkedList;
import java.util.Queue;

public class BFS {
    
    // Solves given maze iteratively, input starting position in maze and size of the maze.
    public static boolean solve(int[][] maze, int x, int y, int sizeX, int sizeY) {
        
        boolean[][] visited = new boolean[sizeX][sizeY];
        Queue<Point> vQueue = new LinkedList<Point>();
        vQueue.add(new Point(x, y, null));
        maze[x][y] = 2;
        visited[x][y] = true;
        
        while (!vQueue.isEmpty()) {
            
            Point p = vQueue.remove();
            
            // 3 is the cell the algorithm is supposed to find.
            if (maze[p.x][p.y] == 3) {
                maze[p.x][p.y] = 2;
                return true;
            }
            
            // Down.
            if (visited[p.x-1][p.y] == false && (maze[p.x-1][p.y] == 0 || maze[p.x-1][p.y] == 3)) {
                maze[p.x-1][p.y] = 2;
                visited[p.x-1][p.y] = true;
                Point nextPoint = new Point(p.x-1, p.y, p);
                vQueue.add(nextPoint);
            }
            
            // Up.
            if (visited[p.x+1][p.y] == false  && (maze[p.x+1][p.y] == 0 || maze[p.x+1][p.y] == 3)) {
                maze[p.x+1][p.y] = 2;
                visited[p.x+1][p.y] = true;
                Point nextPoint = new Point(p.x+1, p.y, p);
                vQueue.add(nextPoint);
            }
            
            // Right.
            if (visited[p.x][p.y+1] == false  && (maze[p.x][p.y+1] == 0 || maze[p.x][p.y+1] == 3)) {
                maze[p.x][p.y+1] = 2;
                visited[p.x][p.y+1] = true;
                Point nextPoint = new Point(p.x, p.y+1, p);
                vQueue.add(nextPoint);
            }
            
            // Left.
            if (visited[p.x][y-1] == false  && (maze[p.x][p.y-1] == 0 || maze[p.x][p.y-1] == 3)) {
                maze[p.x][p.y-1] = 2;
                visited[p.x][p.y-1] = true;
                Point nextPoint = new Point(p.x, p.y-1, p);
                vQueue.add(nextPoint);
            }
        }
        
        return false;
    }
    
    // Node class that holds current position and visitation list.
    private static class Point{
        int x;
        int y;
        Point parent;
        
        public Point(int x, int y, Point parent) {
            this.x = x;
            this.y = y;
            this.parent = parent;
        }
        
        
    }
    
}

测试迷宫

public class TestMazeDFS {
    private static int[][] maze = {
            {1, 1, 1, 1, 1, 1, 1, 1, 1},        
            {1, 0, 0, 0, 0, 0, 0, 0, 1},
            {1, 0, 1, 0, 1, 1, 1, 1, 1},
            {1, 0, 1, 0, 0, 0, 0, 0, 1},
            {1, 1, 1, 1, 1, 0, 1, 0, 1},
            {1, 0, 0, 0, 1, 0, 1, 0, 1},
            {1, 0, 1, 1, 1, 1, 1, 0, 1},
            {1, 0, 0, 0, 0, 0, 0 ,3, 1},
            {1, 1, 1, 1, 1, 1, 1, 1, 1},
        };
    
    public int[][] getMaze(){
        
        return this.maze;
    }
    
    // prints the maze.
    public static void printMaze() {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
//              if (maze[i][j] == 1) {
//                  System.out.print('#');
//              } else {
//                  System.out.print(' ');
//              }
                System.out.print(maze[i][j]);
            }
            System.out.println();
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        TestMazeDFS maze = new TestMazeDFS();
        boolean test = BFS.solve(maze.getMaze(), 1, 1, 9, 9);
        System.out.println(test);
        printMaze();
        
    }
}

1 个答案:

答案 0 :(得分:1)

问题似乎在于您在探索之前更改了 maze 节点的状态。

最简单的例子是一个图,其中源和目标是同一个点。
你首先设置这个点:maze[x][y] = 2 - 然后你才会探索它,并检查它的值是否为3。但现在已经不是这样了。

要解决这个问题,您应该仅在探索节点时将 maze[x'][y'] 的值设置为 2,而不要将其添加到队列中。