我编写了一个使用递归和回溯来找到N-Queens问题解决方案的方法。我现在要做的是修改此方法,以便找到所有可能的解决方案。我假设我需要使用2D整数数组来存储所有解决方案,并且还添加一个计数器,每次找到解决方案时它都会递增。但是,我似乎无法理解如何在找到解决方案并继续回溯以找到所有其他可能的解决方案之后继续使用此方法。我想我要做的就是摆脱“回归真实”;当找到解决方案时会发生这种情况,但后来我不知道如何使该方法以递归方式确定是否找到了解决方案....这是我现在拥有的单解决方案版本:
public boolean placeQueens(int x, int y) {
if (!underAttack(x, y)) {
queen[x] = y;
board[x][y] = true;
if (x + 1 == boardSize
||placeQueens(x + 1, 0)) {
return true;
}
queen[x] = 0;
board[x][y] = false;
}
if (y + 1 == boardSize) {
return false;
}
return placeQueens(x, y + 1);
}
编辑:修正了方法,结果如下。它仍然可能有点混乱,但它的工作原理!我没有打印出找到的每个解决方案,而是将其添加到数组中。我仍然拥有queen []变量的原因是我可以使解决方案数组独立于板状态。我仍然拥有board [] []变量的原因是因为它使underAttack()方法更容易编写(尤其是计算斜率)....无论如何,我非常感谢大家的帮助!
public void placeQueen(int x) {
if (x == N) {
for (int i : queen) {
solution[counter][i] = queen[i];
}
counter++;
return;
}
for (int y = 0; y < N; y++) {
if (!underAttack(x, y)) {
queen[x] = y;
board[x][y] = true;
placeQueen(x + 1);
queen[x] = 0;
board[x][y] = false;
}
}
}
答案 0 :(得分:1)
目前,您只是在寻找一种解决方案。当你找到一个x,y,你可以放置一个女王时,你向前移动一列,并尝试将女王放在下一列。
为了生成所有解决方案,而不是返回true,您可以在最后打印最终数组,回溯并更改当前列的位置并尝试再次生成解决方案。
伪代码可以是这样的
Place(x)
// Here x is the column number where you want to put the queen
if (x == board_size + 1):
print (array A)
return;
for y from 0 to board_size:
if (!underattack(A,x,y)) // A[x] = y => the queen is at row y in col x
A[x] = y
Place(x+1)
return;
这里即使我们找到一个有效的特定(x,y),我们也会回溯并尝试当前x的y的后续值。
答案 1 :(得分:0)
这是NQueens的伪代码: -
void Nqueens(int row,int columns[],int n) {
if(row<n) {
for(int col=0;col<n;col++) {
if(safe(row,col,columns)) {
columns[i] = k;
NQueens(row+1,columns);
}
}
}
else {
printf("solution: \n");
for(int i =0;i<n;i++) {
printf("(%d,%d)\n",i,columns[i]);
}
}
}