逗逼室友说了:
在理!
虽不是第一次接触递归,但是确实实实在在的第一次接触回溯。是琢磨了蛮长时间才编完并测试通过的代码,继承本菜鸟一贯简单的作风,希望能给不太熟悉回溯思想的各位看官一点启发。但是大家在学习回溯时,还是需要明白递归的思想的。不废话
八皇后问题是回溯思想的经典题目,就好像由汉诺塔引入递归一样。具体的要求就不再啰嗦了,google一下一大片(这里给出leetcode中的n皇后的题目大意http://oj.leetcode.com/problems/n-queens/)题目大意:8*8棋盘,8个皇后,怎么放才能保证这几个皇后和谐相处,互不干涉。
算法思想:(为了通俗易懂,本文从1开始计数)
0. 将皇后编号1,2,3,4,5,6,7,8,并且排号为i的皇后,放在第i行
1. 将1号皇后放在第1行(1号皇后是肯定不会冲突的)
2. 1号皇后放好之后,放2号皇后(3号及以后的类似),从第2行第1列开始检测,不冲突就可以落子; 当本行没有合法的位置时,说明上一行皇后放的位置不好,则撤销上一行皇后的位置,并重新摆放(所谓回溯)
3. 如果8个皇后放好之后,按照上文逻辑该放8 + 1 号皇后了,但是已经放完了,所以将摆放结果打印。再重新摆放第8行(很多人不理解这里为什么还回溯)
回溯发生的位置:
1. 皇后i的摆放位置,使得皇后i+1怎么放都不行,即这条路走不通了,回溯(重新摆放皇后i的位置,使得i+1可以摆放,就好像迷宫遇到墙了,要往回走)
2. 8个皇后都摆放完毕,打印出了摆放结果,回溯(就好像迷宫找到了一件宝物(一共需要集齐n件),你找到之后还要回头找另外几件,直到你集齐或者把所有的路都走了(DFS))
算法小结:
1. 对第 i 个皇后,从第i行第1列到第8列,逐个查找,看是否有不冲突的安全位置(特殊情况,皇后1)
2. 如果冲突了,就检查下一列,直到安全的位置,找到最后都不安全,回溯(去找合法序列);
3. 最后一个皇后摆放成功,回溯(去找别的可能性)
public class NQueens { private static int queenNum;//皇后的个数 private static int[] hash;//下标表示i号皇后(皇后i放在第i行)value表示放的列号 private static int count = 0;//合法摆放方式的个数 public void placeQueen(int m) { if (m > queenNum) {//如果摆到了n+1行了,说明前n行都是不冲突的,合法的 count++; System.out.println(Arrays.toString(hash)); //打印合法的摆放结果 for(int i = 1; i <= queenNum; i++){ int column = hash[i];//hash值表示皇后i所在的列号 for(int j = 1; j <= queenNum ;j++){ if(j!= column){ System.out.print("* "); }else{ System.out.print("Q "); } } System.out.println(); } return; } for (int i = 1; i <= queenNum; i++) { //check the column is conflict with former ones or not //if so, check the next column until find a non-conflict column //or until the last column ,return; if (isConfilct(m, i)) { continue; } else {//如果检测到第i列不冲突,是安全的, hash[m] = i;//将皇后m放在第i列 placeQueen(m + 1);//再放皇后m+1, //如果皇后m+1放完并返回了 //两种可能: //1:冲突,返回了 //2.一直将所有的皇后全部放完并安全返回了 //将皇后m回溯,探索新的可能或者安全的位置 hash[m] = -1; //其实这里没必要将m重新赋值的,因为检测到下一个 //安全位置的时候会把hash[m]覆盖掉的 //但是为了更好的体现“回溯”的思想,在这里画蛇添足了 } } } /** * 检测冲突 * @param index * 表示行号 * @param hash * 值表示列号 * @return */ private boolean isConfilct(int row, int column) { if(row == 1){//第1行永远不会冲突 return false; } //只需要保证与那些已经就位的皇后不冲突即可 for (int i = 1; i < row; i++) { if (hash[i] == column || ( column - row) == (hash[i] - i) || (row - column)== (i-hash[i]) || (row + column) == (hash[i] + i)) { return true; } } return false; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); queenNum = sc.nextInt(); hash = new int[queenNum + 1]; for (int i = 0; i < hash.length; hash[i++] = -1);//初始化棋盘 NQueens demo = new NQueens(); demo.placeQueen(1); System.out.println(count); } }
我取的queenNum = 4时,打印出来的结果是
[-1, 2, 4, 1, 3] //比如hash[1]= 2表示1号皇后在第1行第2列
* Q * *
* * * Q
Q * * *
* * Q *
[-1, 3, 1, 4, 2]
* * Q *
Q * * *
* * * Q
* Q * *
2
相关推荐
回溯法实现n皇后问题,并输出每种放法的皇后位置
N皇后问题(n-queen problem)是一个经典的组合优化问题,也是一个使用回溯法(backtracking)的典型例子。回溯法是一种系统地搜索问题解的方法。 此文档包含算法分析、代码实现、演示程序、演示界面。
算法分析与设计 用回溯法实现n皇后问题(java源码)
n 皇后问题是一道经典的回溯算法问题,其目标是在一个 � × � n×n 的棋盘上放置 � n 个皇后,使得任意两个皇后都不能在同一行、同一列或同一斜线上。 栈可以用来辅助实现回溯算法,本质上就是手动维护了递归...
这是一个用Java实现的关于N皇后问题的算法 其中包括回溯和迭代两种算法
使用分支限界法解决N皇后问题。因为是广度优先,而且占用比较多的额外空间,所以并不是解N皇后问题的很好的算法,主要是理解分支限界法的使用。
这是 Java 中著名的 N Queens 问题的实现。 这使用了递归回溯的概念。 此类使用辅助函数 place(),如果可以将皇后放置在给定的坐标中,则该函数返回 true。 positionInRow - 该数组将保存放置的皇后的列值,其中...
java和c++都有,算法为回溯。n后问题 注:i-j=k-l 或 i+j=k+l 说明2个皇后在对角线上
NQueens_Backtracking 回溯算法解决N皇后问题
实验1 最大公约数(包括连续整除、欧几里得、分解质因数算法) 实验2 最近对问题(包括蛮力算法和分治算法) ...实验6 n皇后_2009(包括回溯算法) 以上几个实验基本上都是采用不同的算法实现,所有代码均为原创。
用Java编写的八皇后问题 八皇后问题 将八皇后扩展为N皇后问题
利用回溯法求解八皇后问题,从八皇后问题延伸到n皇后问题。利用水平,主对角线,反对角线三个数组简化算法。 使用方法: 输入要求解的n皇后数目,程序自动输出每种具体方案和总的方法数。
本程序现实了N后问题的界面演示,在该程序中你可以查看各种N后问题的解决方案皇后的安放位置。这是Netbeans下可以直接运行的。
由N2个方块排成N行N列的正方形,称为N元棋盘,在N元棋盘上放置N个皇后,如果某两个皇后位于N元棋盘的同一行或同一列或同一斜线(斜率为±1)上,则称它们在互相攻击,试设计算法找出使N个皇后互不攻击的所有布局。
用四种算法解决n皇后问题,java语言,带界面,完整工程,
15个典型的递归算法的JAVA实现,求N的阶乘、欧几里德算法(求最大公约数)、斐波那契数列、汉诺塔问题、树的三种递归遍历方式、快速排序、折半查找、图的遍历、归并排序、八皇后问题(回溯、递归)、棋盘覆盖(分治,...
八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线...
CISC3150-HW3 根据用户的输入值计算nQueens 参考拜尔斯(Byers),马克(Mark)(2013)八皇后算法(Queens Queen Algorithm)取自 CSBreakdown(2015)N皇后问题-从检索的回溯古普塔(Sukrit)(2014)The n Queen...
实现将使用异步回溯(ABT)算法来协作解决n皇后难题的Java代理。 在NxN棋盘上有N个索引为0,..,n-1的代理,代表N个皇后。 特工i在棋盘的第i行控制女王。 任务是为每个特工/女王找到对应的列,以使没有两个特工/...
高级数据结构动态规划、回溯和树遍历问题Repository 包含基于 BackTracking 的示例的基本知识: NQueen 问题:是将 N 个皇后放在 N*N 棋盘上的问题,以便没有两个皇后互相攻击。 回溯算法的想法是将皇后一个一个地...