dfs迷宫解算器在正确时返回false

oug3syen  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(428)

我现在正在做一个小的迷宫解算器项目,以便更好地掌握深度优先搜索等算法。它的工作原理是将当前位置转换为2,然后检查其中一个位置(上、下、左或右),如果它是0(路径),它将向前移动,直到它被1(墙)包围,然后它是一个死胡同,它将返回。
然而,奇怪的是,我的迷宫解算器一直返回false,即使它找到了3号(结尾)。所以我有两个问题,是什么导致它返回false,以及什么可以在解算器中更改,以便只有最短路径才有数字2(即当它回溯时,它会将死端路径变成其他路径)?
提前谢谢!
迷宫求解器

public class DFS {

    private int[][] maze;

    public DFS(int[][] maze) {

        this.maze = maze;
    }

    // Solves given maze recursively, input starting position in maze.
    public boolean solve(int x, int y) {

        maze[x][y] = 2;

        // 3 is the cell the algorithm is supposed to find.
        if (maze[x][y] == 3) {
            return true;
        }

        // Looks up.
        if (x > 0 && maze[x-1][y] == 0  && solve (x-1, y) ) {
            maze[x][y] = 2;
            return true;
        }
        // Looks down
        if (x < maze.length && maze[x+1][y] == 0  && solve (x+1, y) ) {
            maze[x][y] = 2;
            return true;
        }
        // Looks right.
        if (y < maze.length && maze[x][y+1] == 0  && solve (x, y+1) ) {
            maze[x][y] = 2;
            return true;
        }
        // Looks left.
        if (y > 0 && maze[x][y-1] == 0  && solve (x, y-1) ) {
            maze[x][y] = 2;
            return true;
        }

        return false;
    }

}

硬编码迷宫

import java.util.ArrayList;

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 ,0, 1},
            {1, 1, 1, 1, 1, 1, 1, 3, 1},
        };

    public int[][] getMaze(){

        return this.maze;
    }

    public static void main(String[] args) {

        DFS dfs = new DFS(maze);
        boolean test = dfs.solve(1, 1);
        System.out.println(test);

    }
}

打印时溶液的图像。

https://imgur.com/a/uqhp81o

8hhllhi2

8hhllhi21#

看一眼就知道你做错了:

maze[x][y] = 2;

        // 3 is the cell the algorithm is supposed to find.
        if (maze[x][y] == 3) { // <-- It will never be 3
            return true;
        }

同样在每个if检查中: if (x > 0 && maze[x-1][y] == 0 && solve (x-1, y) ) { ,你只是拜访有价值的邻居 0 . 所以很明显,你永远不会访问一个有价值的细胞 3 . if检查应该类似于: if (x > 0 && (maze[x-1][y] == 0 || maze[x-1][y] == 3) && solve (x-1, y) ) { 请注意,回溯时,需要将状态恢复到原始状态。也就是说, maze[x][y] 在返回false时应该具有原始值。
也许试试这个?

public boolean solve(int x, int y) {
        // 3 is the cell the algorithm is supposed to find.
        if (maze[x][y] == 3) {
            maze[x][y] = 2;
            return true;
        }

        int orig = maze[x][y];
        maze[x][y] = 2;

        // Looks up.
        if (x > 0 && (maze[x-1][y] == 0 || maze[x-1][y] == 3)  && solve (x-1, y) ) {
            //maze[x][y] = 2;
            return true;
        }
        // Looks down
        if (x < maze.length && (maze[x+1][y] == 0 || maze[x+1][y] == 3)  && solve (x+1, y) ) {
            //maze[x][y] = 2;
            return true;
        }
        // Looks right.
        if (y < maze.length && (maze[x][y+1] == 0 || maze[x][y+1] == 3)  && solve (x, y+1) ) {
            //maze[x][y] = 2;
            return true;
        }
        // Looks left.
        if (y > 0 && (maze[x][y-1] == 0 || maze[x][y-1] == 3)  && solve (x, y-1) ) {
            //maze[x][y] = 2;
            return true;
        }

        maze[x][y] = orig;
        return false;
    }

工作方案:https://onlinegdb.com/ryxopkgcaw

相关问题