java - 使用回溯递归的 8 皇后问题

标签 java language-agnostic recursion n-queens

我一直在研究 8 皇后问题,但我被卡住了。我不要代码。我希望得到指导和指导,以便了解如何使用回溯递归自行解决此问题。

程序应该像两个解决方案一样,通过在 ASCII 中绘制皇后的位置来枚举 N 皇后问题的所有解决方案 here .

到目前为止我的伪代码是:

void queen(int n){

   for( int i = 0; i < n; i++){

       place queen[ i ] on row i;

       for(int j = 0 ; j < n ; j++){
               if( queen[ i ] is not in the same column as queen[0] through queen[ i - 1 ]  &&
                   queen[ i ] is not on the same major diagonal with queen[0] through queen[ i -1 ]  &&
                   queen[ i ] is not on the same minor diagonal with queen[0] through queen[ i -1 ]  ) {
                              print 'Q ';
                   }
               else{
                              print '* ';
                   }

               System.out.println();
         }

         System.out.println();

  }

}

我的伪代码中没有任何回溯递归,因为我不知道该怎么做。

非常感谢任何帮助。请不要代码。

(响应 Nemo 的更新):

solver(int n, Board b){
    for(int i = 0; i < b.length; i++){
       place queen in column i;
       for(int j = 0; j < b.length; j++){
           change b;
           solver(n+1,changed b); 
       }
    }
}

是否正确?

(更新 2):

 solver8(board /* with queens presented in first 7 columns */){
    // place a queen in the 8th column;
    for(each possible placement of the queen in column 8 
        or in other words int i = 0; i < board.length; i++ ){
             place the queen and print the board
    }
}


 solver7(board /* with queens presented in first 6 columns */){
    // place a queen in the 7th column;
    for(each possible placement of the queen in column 7 
        or in other words int i = 0; i < board.length; i++ ){
             solver8(board with queens placed in first 7 columns);
    }
}


 solver6(board /* with queens presented in first 5 columns */ ){
    // place a queen in the 6th column;
    for(each possible placement of the queen in column 6 
        or in other words int i = 0; i < board.length; i++ ){
             solver7(board with queens presented in first 6 columns);
    }
}

以此类推直到

 solver1(1, empty board){
     for(int i = 0; i < board.length; i++){
        place queen in row[i] of column 1;
        solver2(board with queen in row[i] of column 1);
      }
}

更新 3(已编辑):

private int numberOfQueens = 8;
solver(int n, Board b){

        for(int r = 0; r < b.length; r++){

               place queen in row[r] of column[n];

               if(n == numberOfQueens){
                    print the board;
                    return;
                }
                else{
                    solver(n+1, board with queen in row[r] of column[n]);
                }
           }
     }
}

最佳答案

对此类问题使用递归的目的是,它们允许您根据“我现在已经放置了k个皇后;如果总共有皇后区是 n?”所以递归函数应该有两个参数:目标皇后数和目前放置的皇后数。编写函数时,您的首要目标是尝试放置第 k 个皇后的不同方法。但是当您选择了一个可能的放置并发现它有效时,您需要放置剩余的 n - k - 1 个皇后。我们应该怎么做?答案是:递归!使用参数 k - 1 调用函数(从自身内部)以指示您要放置剩余的 k - 1 个皇后。每当您用尽所有可能性(或发现不可能)时,只需从该函数返回 - 然后您将返回到上一个函数调用(例如,尝试放置第 k 个皇后的函数调用) .

编辑:您还需要创建一个二维数组来表示板的当前状态;此数组必须作为附加参数发送给递归函数,或者作为包含该方法的类的字段保留。

至于回溯,只需确保使用 k + 1 调用的函数在之前从棋盘上移除第 k + 1 个皇后即可实现返回;这基本上是说“我们现在(未成功)尝试了所有放置其余皇后的方法 - 基于已经放置的 k 个皇后的位置。他们都没有成功,所以请调整前 k 个皇后的位置(这将由用 k 调用的函数以及调用该函数的函数等完成)并尝试又来了。”

关于java - 使用回溯递归的 8 皇后问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6337765/

相关文章:

java - 使用 Swing 计时器更新标签

math - float 学坏了吗?

c# - 如何从一维 int 数组返回数字网格?

recursion - 如何在没有运行时多态性的情况下对迭代器执行 N 次 `flat_map`(或类似操作)?

python - 在Python中的嵌套字典中存储目录结构

java - 为什么有些 double 除法在java操作中是正确的?

Java守护进程最好的跨平台解决方案?

java - OpenCV:从 Canny 画线

algorithm - 删除数字的低位数字

java - 递归和循环哪个更有效?