我写了一个关于N-Queens拼图的Java小算法(带有c * c棋盘)。你会在下面找到我的递归方法的代码。
找不到所有解决方案。
这个想法是在main方法中首先调用我的函数给它最大数量的皇后,直到找到解决方案,没有任何皇后的棋盘和这些新皇后的坐标:x = 0,y = 0。
该功能将通过棋盘。对于每个方格,它测试是否可以放置女王(0; 0)(即:没有威胁)。可以放置女王(0; 0)?好吧,我们这样做(修改棋盘),我们调用函数(递归调用)。这个递归调用是通过以下方式完成的:“最大数量的皇后 - 1”,修改后的棋盘和“新女王的y + 1”(稍微复杂一些)。
&安培;&安培; Q&安培;
Q&安培;&安培;&安培;
&安培;&安培;&安培; Q
&安培; Q&安培;&安培;
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);
}
}
}
}
答案 0 :(得分:1)
哦,对,那是因为你以递归方式打电话,你正在做setQueen(nb_queens-1, chessboard, i, z+1, solutions);
。 z+1
部分是问题所在,它总会找到你放在全球董事会的第一位女王右侧的解决方案。
因此,问题是for循环充当if(z>=y)
,因为它从y
开始。 i = x
(阅读第一行),但i > x
时没有。因此,一个简单的解决方法是在第一个y = ( i == x ) ? y : 0
循环之后放置for
。
甚至有更清晰的解决方案,比如使用单个索引来完成整个棋盘。
我还建议你将你的参数重命名为startX和startY(而不是x和y,你可以在循环中使用x和y来更清楚)。
Edit2:由于游戏规则,在同一条线上永远不会有女王,所以你可以进行setQueen(nb_queens-1, chessboard, i+1, 0, solutions);
(i+1
之类的递归调用,因为你直接在下一行开始)。因此,您甚至可以从int y
方法中移除setQueen
参数,并始终在z loop
处启动。