陷入N皇后java算法。(回溯)

陷入N皇后java算法。(回溯),java,algorithm,recursion,backtracking,n-queens,Java,Algorithm,Recursion,Backtracking,N Queens,有人能给我一个关于java程序的提示或指导吗?我陷入了回溯的想法。这是代码。如果你看一下solve()方法,它会递归地调用自己,但是我被困在一个点上,它无法放置更多的皇后,并试图回溯 public NQueens(int N) { this.N = N; board = new boolean[N][N]; solved = solve(N); if(solved == true) { System.out.println(N+"x"+N+

有人能给我一个关于java程序的提示或指导吗?我陷入了回溯的想法。这是代码。如果你看一下solve()方法,它会递归地调用自己,但是我被困在一个点上,它无法放置更多的皇后,并试图回溯

public NQueens(int N)
{
    this.N = N;
    board = new boolean[N][N];
    solved = solve(N);
    if(solved == true)
    {
        System.out.println(N+"x"+N+" solution:");
        printBoard(N);
    }
    else
    {
        System.out.println("There is no solution for "+N+"x"+N+" board");
    }
}

public boolean solve(int waitingQueens)
{
    if(waitingQueens == 0) return true;

    for(int row = 0; row < N; row++)
    {

        for(int column = 0 ; column < N ; column++)
        {
            if(isValid(row, column))
            {
                board[row][column] = true;
                waitingQueens--;
                boolean solved = solve(waitingQueens);

                if(!solved)
                {
                    board[row][column] = false;

                    solved = solve(waitingQueens);
                }
                return solved;
            }

        }

    }

    return false;
}

public boolean isValid(int rowParam, int columnParam)
{
    for(int x = 0; x < N; x++)
    {
        for(int y = 0; y < N; y++)
        {
            if(board[x][y] == true) //find the already placed queens on the board and check if the queen about to be placed is on a valid position
            {
                if(x == rowParam) //check the validity of the row
                    return false;
                if(y == columnParam) //check the validity of the column
                    return false;
                if(Math.abs(x-rowParam) == Math.abs(y-columnParam)) //check the validity of the diagonals
                    return false;
            }
        }
    }
    return true;
}

public void printBoard(int printParam)
{
    for(int x1 = 0; x1 < printParam; x1++)
    {
        for(int y1 = 0; y1 < printParam; y1++)
        {
            if(board[x1][y1] == true)
            {
                System.out.print("Q ");
            }
            else{
                System.out.print("* ");
            }
        }
        System.out.println();
    }
    System.out.println();
}
public nqueen(int N)
{
这个,N=N;
board=新布尔值[N][N];
已求解=求解(N);
如果(已解决==真)
{
System.out.println(N+“x”+N+“溶液:”);
印刷电路板(N);
}
其他的
{
System.out.println(“没有针对“+N+”x“+N+”板的解决方案”);
}
}
公共布尔解算(int waitingQueens)
{
if(waitingQueens==0)返回true;
对于(int行=0;行
我推测这就是您试图实现的算法:假设您已经有了
M
皇后(看起来像
M
=
N-waitingqueen
或其他什么)。然后,你寻找每一个可以放置女王的空广场。如果在那里放置皇后是有效的,您可以将
board
中的正方形设置为
true
,然后递归调用
solve
,查看是否可以放置
waitingQueens-1
更多皇后

最大的问题在于,如果递归的
solve
返回
false
,会发生什么情况。假设它是一个4x4板,
waitingQueens
是4。您将放置第一个皇后,然后使用
waitingQueens=3
调用
solve
。但假设它说没有解决办法。然后执行以下操作:

            if(!solved)
            {
                board[row][column] = false;
                solved = solve(waitingQueens);
            }
这将把方块设置为
false
,这意味着电路板现在又空了。但是,然后您使用
waitingQueens=3
调用
solve(waitingQueens)
,这意味着您的递归
solve
现在将寻找板上只有3个皇后的解决方案。这不可能是对的。将
waitingQueens
重新递增到4将导致无限递归,因为
solve(4)
将使用相同的空板调用
solve(4)

这里的问题是,你已经在一个双循环中,将寻找每一个可以放置女王的正方形。如果您试图将皇后放置在某个位置,但没有成功(递归调用失败),则删除皇后,然后让双循环为您找到下一个有效的平方。您不想执行另一个递归调用。因此,应该删除上面的
solve(waitingQueens)
调用

此外,还需要解决这一问题:

            waitingQueens--;
            boolean solved = solve(waitingQueens);
减少
waitingQueens
是个坏主意,因为如果
solve
返回
false
,并且必须返回到下一个循环迭代,
waitingQueens
将比以前少一个,这是不好的。您可以通过在
if(!solved)
分支中说
waitingQueens++
来恢复它,但是为什么要麻烦呢?将
waitingQueens
放在一边,将上面的两行替换为

            boolean solved = solve(waitingQueens-1);

我不确定这两个修复是否足以产生正确的答案,但它们只是一个开始。我还想提到另外几件事,尽管这些只是优化:(1)你在
solve
中的循环甚至不应该看到不是空的方块。按照您编写的方式,
isValid
将返回
false
,如果您给它一个不是空的正方形,但它会以迂回的方式返回。我可能会在调用
isValid
之前检查方块是否为空。(2) 一旦将
M
皇后放置在第0行到
M-1
行中,递归调用甚至不应该查看这些行,因为我们知道不能在同一行中有两个皇后。如果您查看第
M行,但没有找到解决方案,您可以立即放弃,因为我们知道正确的解决方案必须在每一行都有一个皇后。因此,您实际上只需要在
solve
中执行一个循环,我想这就是您试图实现的算法:假设板上已经有
M
皇后(看起来像
M
=
N-waitingQueens
之类)。然后,你寻找每一个可以放置女王的空广场。如果在那里放置皇后是有效的,您可以将
board
中的正方形设置为
true
,然后递归调用
solve
,查看是否可以放置
waitingQueens-1
更多皇后