Java 递归N皇后:缺少解

Java 递归N皇后:缺少解,java,recursion,n-queens,Java,Recursion,N Queens,我编写了一个N皇后难题的Java小算法(使用c*c棋盘)。下面是我的递归方法的代码 它没有找到所有的解决方案 我的功能是什么 这个想法是,在main方法中,首先调用我的函数,给它最大数量的皇后,直到找到一个解决方案,没有皇后的棋盘和这些新皇后坐标:x=0,y=0 该函数将通过棋盘。对于每个方块,它测试皇后(0;0)是否可以放置(即:无威胁)。皇后(0;0)可以放置吗?我们这样做(修改棋盘)并调用函数(递归调用)。这个递归调用是通过“最大皇后数-1”、修改后的棋盘和“新皇后的y+1”(稍微复杂一点

我编写了一个N皇后难题的Java小算法(使用c*c棋盘)。下面是我的递归方法的代码

它没有找到所有的解决方案

我的功能是什么 这个想法是,在main方法中,首先调用我的函数,给它最大数量的皇后,直到找到一个解决方案,没有皇后的棋盘和这些新皇后坐标:x=0,y=0

该函数将通过棋盘。对于每个方块,它测试皇后(0;0)是否可以放置(即:无威胁)。皇后(0;0)可以放置吗?我们这样做(修改棋盘)并调用函数(递归调用)。这个递归调用是通过“最大皇后数-1”、修改后的棋盘和“新皇后的y+1”(稍微复杂一点)完成的

找到n=4和c=4的解决方案(通常有两种解决方案…!) &&Q&

Q&&&

&&&Q

&Q&&

我的函数的最新代码
private static void setQueen(int nb_queen,ArrayList棋盘,int x,int y,ArrayList解决方案){
如果(nb_queens==0){//如果没有剩余的皇后,这意味着我们找到了一个解决方案
拉丝棋盘(棋盘);
解决方案。添加(棋盘);
}
对于(int i=x;i
旧代码
private static void setQueen(int nb_queen,ArrayList棋盘,int x,int y,ArrayList解决方案){
if(nb_queens==0){
drawschessboard(棋盘);//在dessine-cette解决方案上,不存在一个加上dereineáplacer=>
解决方案。添加(棋盘);
}
对于(int i=x;i=宽度)?0:z+1,解);
棋盘.get(z).set(i,false);
}
}
}
}

哦,对了,那是因为你如何递归调用,你的动作
setQueen(nb_queens-1,棋盘,i,z+1,解)
z+1
部分是问题所在,它总是在您放置在全球板上的第一个皇后的右侧找到解决方案

编辑:啊,你以前找到过,很好

因此,问题是for循环在(z>=y)
时充当
函数,因为它从
y
开始。当
i=x
(读取第一行)时可以,但当
i>x
时则不行。所以一个简单的解决方法是把
y=(i==x)?y:0
就在第一个
for
循环之后

甚至还有更干净的解决方案,比如使用单个索引遍历整个棋盘

我还建议您将参数重命名为startX和startY(而不是x和y,您可以在循环中使用x和y来更清楚)


Edit2:由于游戏规则,在同一行上永远不会有皇后,因此您可以进行递归调用,如
setQueen(nb_queens-1,棋盘,i+1,0,解决方案)
i+1
,因为您直接从下一行开始)。因此,您甚至可以从
setQueen
方法中删除
int y
参数,并始终在0处启动
z循环

是否找到任何解决方案?结果是什么?另外,把
放在isQueenalReadyPresent(i,z,chessboard)
上,它应该不会有问题,但谁知道呢。而且,同时使用递归和迭代并没有真正的用处……我编辑了OP以显示结果:)啊,是的,现在我明白了为什么要使用递归和迭代。但事实上,它似乎缺少很多结果,不是还有很多吗?比如,这些解的对称性?像&&Q&&&Q&它与你的第一个结果是对称的。是的,缺少很多解决方案。我不明白为什么。我不认为这是因为
isQueenAlreadyPresent
但是。你能添加这个函数的代码吗?如果我写:
int new_z=(z+1>=WIDTH)?0:z+1
然后使用
new_z
(而不是
z
)进行递归调用,似乎在n=4和c=4时仍缺少一些解决方案。我应该找到两个解决方案,而我只有一个。你知道为什么吗?你可以通过对(int i=0;)和(int z=0;)执行
来轻松解决这个问题。
你很难看,复杂性为n^3。(编写一个更好的解决方案)所以你认为我不能将我的
I,z=a_参数保留在我的两个
for
中?是的,你可以,但这需要我在编辑中编写的另一个解决方案。我编辑了我的OP(以显示新代码)。我可以指出你的登录,因为你帮助了我吗?我的更改是:递归调用中的“I+1,0”,我删除了
y=(I==x)?y:0
private static void setQueen(int nb_queens, ArrayList<ArrayList<Boolean>> chessboard, int x, int y, ArrayList<ArrayList<ArrayList<Boolean>>> solutions) {
    if (nb_queens == 0) { // If there isn't any queen remaining, it means we found a solution
        drawChessboard(chessboard);
        solutions.add(chessboard);
    }

    for(int i = x; i < chessboard.size(); i++) {
        for (int z = y; z < chessboard.get(i).size(); z++) {
            if(!canBePlaced(i, z, chessboard)) {
                chessboard.get(z).set(i, true); // On peut donc placer cette reine(x;y) et on le fait
                setQueen(nb_queens-1, chessboard, i+1, 0, solutions);
                chessboard.get(z).set(i, false);
            }
        }
    }

}
private static void setQueen(int nb_queens, ArrayList<ArrayList<Boolean>> chessboard, int x, int y, ArrayList<ArrayList<ArrayList<Boolean>>> solutions) {
    if (nb_queens == 0) {
        drawChessboard(chessboard); // Il n'y a plus de reine à placer => on dessine cette solution
        solutions.add(chessboard);
    }

    for(int i = x; i < chessboard.size(); i++) {
        for (int z = y; z < chessboard.get(i).size(); z++) {
            if(!isAQueenAlreadyPresent(i, z, chessboard)) {
                chessboard.get(z).set(i, true); // On peut donc placer cette reine(x;y) et on le fait
                setQueen(nb_queens-1, chessboard, i, (z+1 >= WIDTH) ? 0 : z+1, solutions);
                chessboard.get(z).set(i, false);
            }
        }
    }

}