递归回溯返回更新的值

时间:2013-10-02 23:34:23

标签: java recursion backtracking

我正在创建一个旨在递归导航迷宫的程序。代码:

public static boolean traverse(int maze[][], coordinate start)
{
    //recursion: traverse(maze, updated coordinates)

    if(maze[start.y+1][start.x] == 2 || maze[start.y-1][start.x] == 2 || maze[start.y][start.x+1] == 2 || maze[start.y][start.x - 1] == 2)
    {
        display(maze);
        System.out.println("DONE");
        return true;
    }

    else 
    {
        if(north(maze, start) == true)
        {
            maze[start.y-1][start.x] = 4;
            display(maze);
            coordinate temp = start; 
            temp.y--;
            if (traverse(maze, temp) == false)
            {
                maze[start.y][start.x] = 3;

            }
        }   

        if(west(maze, start) == true)
        {
            maze[start.y][start.x-1] = 4;
            display(maze);
            coordinate temp = start;
            temp.x--;
            if (traverse(maze, temp) == false)
            {
                maze[start.y][start.x] = 3;
            }
        }


        if(south(maze, start) == true)
        {
            maze[start.y+1][start.x] = 4;
            display(maze);
            coordinate temp = start;
            temp.y++;
            if (traverse(maze, temp) == false)
            {
                maze[start.y][start.x] = 3;
            }
        }

        if(east(maze, start) == true)
        {
            maze[start.y][start.x+1] = 4;
            display(maze);
            coordinate temp = start;
            temp.x++;
            if (traverse(maze, temp) == false)
            {
                maze[start.y][start.x] = 3;
            }
        }   


    }

    return false;
}

然而,每当我走到死胡同时,它都不会回溯。当我调试时,它显示当程序从递归或“回溯”返回时,我的起始值被固定在停留在我的死角空间。

例如:

1 1 1 1 1 
1 4 4 4 1 
1 9 1 4 1 
1 1 1 4 1 
1 4 4 4 1 
1 4 1 0 1 
1 4 1 0 1 
1 1 1 2 1  

9是我的出发点。 2是我的出口。 4是我的道路。 1代表墙壁。当我到达死胡同时(在这种情况下,第7行,第2列)。我的位置将等于整个程序其余部分的死角空间。为什么?

2 个答案:

答案 0 :(得分:0)

当您向上移动堆栈时,值会更新并且永远不会“回溯”,因为它们不会在每个级别保留其原始值,如果每个节点在更新时都不保留原始值,则回溯基本上是在树上行走在每个级别,每个节点都将具有叶节点的值,当满足叶节点时,节点不记得它们的原始值。相反,你需要在遍历堆栈时传递一个新值而不更新每个堆栈以记住他们的父级调用它们时所拥有的内容。

最简单的方法是尝试,

 traverse(int maze[][], int x , int y)

您的后续通话看起来像

 if(north(maze, x , y) == true)
    {
        maze[y-1][x] = 4;
        display(maze);

        //temp.y--;
        if (traverse(maze, x , y-1) == false)
        {
            maze[y][x] = 3;

        }
    }

或者您可以在返回当前堆栈后重置您的值,

我还没有检查你的其余代码,但这可能是代码不回溯的原因

答案 1 :(得分:0)

你可以缩短那个很多。试试他的代码。

public static boolean traverse(int[][] maze, int x, int y) {
    if(y >= maze.length || x >= maze[y].length) return false;
    int value = maze[y][x];
    if(value == 2) {
        display(maze);
        System.out.println("DONE");
        return true;
    } else if(value == 0 || value == 9) {
        maze[y][x] = 4;
        boolean success = false;
        loop:
        for(int dy = -1; dy <= 1; dy++) {
            for(int dx = -1; dx <= 1; dx++) {
                if(dx == 0 && dy == 0 ||
                   dx != 0 && dy != 0) continue;
                success |= traverse(maze, x + dx, y + dy);
                if(success) break loop;
            }
        }
        maze[y][x] = value;
        return success;
    }
    return false;
}

public static void main(String[] args) {
    int[][] maze = {{1, 1, 1, 1, 1}, 
                    {1, 0, 0, 0, 1},
                    {1, 9, 1, 0, 1},
                    {1, 1, 1, 0, 1},
                    {1, 0, 0, 0, 1},
                    {1, 0, 1, 0, 1},
                    {1, 0, 1, 0, 1},
                    {1, 1, 1, 2, 1}};
    int x = 0, y = 0;
    loop:
    for(y = 0; y < maze.length; y++) {
        for(x = 0; x < maze[y].length; x++) {
            if(maze[y][x] == 9) break loop;
        }
    }
    boolean success = traverse(maze, x, y);
    System.out.println();
    System.out.println(success);
    display(maze);
}