【发布时间】:2015-12-14 09:17:32
【问题描述】:
我正在做一些递归练习,遇到了 nQueens 问题here。
我不确定我是否误解了递归发生了什么,但我不明白这段代码(如下)如何打印问题的多个解决方案。
例如,如果我使用 4 Queen 解决方案运行程序,它会打印出:
* Q * *
* * * Q
Q * * *
* * Q *
* * Q *
Q * * *
* * * Q
* Q * *
我也在一步步看,还是不太明白。
这是我认为正在发生的事情:
1. isConsistent 正在检查逻辑/在当前位置放置女王是否安全
2. printQueens 正在打印电路板
3. enumerate(int[] q, int n) 递归地将皇后放在一个解决方案中
4.(我猜) enumerate(int N) 是通过多板解决方案枚举的,但它只被调用一次。所以,这不可能。所以,我的下一个想法是它只是一种调用递归枚举方法的方法。但是,这意味着一旦递归完成找到第一块板的解决方案,它应该停止。所以,我回到我原来的问题:
它如何/在哪里计算板的多个解决方案?
我知道这可能很容易,但即使使用调试器,我也无法理解正在发生的事情。如果有人能解释它从哪里开始计算板的第二个解决方案,我将不胜感激。
/******************************************************************************
* Compilation: javac Queens.java
* Execution: java Queens N
*
* Solve the 8 queens problem using recursion and backtracing.
* Prints out all solutions.
*
* Limitations: works for N <= 25, but slows down considerably
* for larger N.
*
* Remark: this program implicitly enumerates all N^N possible
* placements (instead of N!), but the backtracing prunes off
* most of them, so it's not necessarily worth the extra
* complication of enumerating only permutations.
*
*
* % java Queens 3
*
* % java Queens 4
* * Q * *
* * * * Q
* Q * * *
* * * Q *
*
* * * Q *
* Q * * *
* * * * Q
* * Q * *
*
* % java Queens 8
* Q * * * * * * *
* * * * * Q * * *
* * * * * * * * Q
* * * * * * Q * *
* * * Q * * * * *
* * * * * * * Q *
* * Q * * * * * *
* * * * Q * * * *
*
* ...
*
******************************************************************************/
public class Queens {
/***************************************************************************
* Return true if queen placement q[n] does not conflict with
* other queens q[0] through q[n-1]
***************************************************************************/
public static boolean isConsistent(int[] q, int n) {
for (int i = 0; i < n; i++) {
if (q[i] == q[n]) return false; // same column
if ((q[i] - q[n]) == (n - i)) return false; // same major diagonal
if ((q[n] - q[i]) == (n - i)) return false; // same minor diagonal
}
return true;
}
/***************************************************************************
* Print out N-by-N placement of queens from permutation q in ASCII.
***************************************************************************/
public static void printQueens(int[] q) {
int N = q.length;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (q[i] == j) StdOut.print("Q ");
else StdOut.print("* ");
}
StdOut.println();
}
StdOut.println();
}
/***************************************************************************
* Try all permutations using backtracking
***************************************************************************/
public static void enumerate(int N) {
int[] a = new int[N];
enumerate(a, 0);
}
public static void enumerate(int[] q, int n) {
int N = q.length;
if (n == N) printQueens(q);
else {
for (int i = 0; i < N; i++) {
q[n] = i;
if (isConsistent(q, n)) enumerate(q, n+1);
}
}
}
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
enumerate(N);
}
}
【问题讨论】: