【算法系列-11】回溯算法-八皇后

来源:互联网 发布:如何在淘宝上卖鱼 资质 编辑:程序博客网 时间:2024/06/15 09:17

声明:内容来自网络

概念

回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。


八皇后问题

国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。


基本思想

八皇后问题就是回溯算法的典型,第一步按照顺序放一个皇后,然后第二步符合要求放第2个皇后,如果没有位置符合要求,那么就要改变第一个皇后的位置,重新放第2个皇后的位置,直到找到符合条件的位置就可以了。


分析

为了分析简捷,以4皇后为例:

首先利用回溯算法,先给第一个皇后安排位置,如下图所示,安排在(1,1)然后给第二个皇后安排位置,可知(2,1),(2,2)都会产生冲突,因此可以安排在(2,3),然后安排第三个皇后,在第三行没有合适的位置,因此回溯到第二个皇后,重新安排第二个皇后的位置,安排到(2,4),然后安排第三个皇后到(3,2),安排第四个皇后有冲突,因此要回溯到第三个皇后,可知第三个皇后也就仅此一个位置,无处可改,故继续向上回溯到第二个皇后,也没有位置可更改,因此回溯到第一个皇后,更改第一个皇后的位置,继续上面的做法,直至找到所有皇后的位置,如下图所示。


这里为什么我们用4皇后做例子呢?因为3皇后是无解的。

代码

首先,伪代码

//寻找当前行的皇后应该位于哪一列void FindQueen(row){  for(int i=0;i<8;i++)  {    //1.判断当前是否满足要求    if(Is_Meet(row,i))    {    //2.判断当前是否是最后一行了      if(最后一行){输出操作,并返回}    //3.执行下一行匹配      FindQueen(row+1);    //4.如果进行到这一步,说明步骤三已经操作完,没有合适结果,需要返回上一步,即执行当前for的下一个循环    }  }}

具体实现:

public class EightQueen {private int queen[] = {-1,-1,-1,-1,-1,-1,-1,-1};int total = 0;/** * 判断是否冲突 * @param row * @param column * @return false 冲突 true 无冲突 */public boolean isMeet(int row, int column){int c;for(int r=0; r<row; r++){c = queen[r];/*同一行*/if(column == c)return false;/*正对角线*/if((row + column) == (c + r))return false;/*反对角线*/if((column - row) == (c - r))return false;}return true;}/** * 在棋盘上摆放皇后 * 通过递归(堆栈原理)实现的回溯 * @param row */public void findQueen(int row){for(int c=0; c<8; c++){if(isMeet(row, c)){queen[row] = c;if(row == 7){total++;display();return;}/*递归,放置下一枚皇后*/findQueen(row + 1);}/*发生冲突的情况,没有符合条件的结果,需要查看for的下一个循环, * 如果循环结束仍然没有符合的条件,则返回上一步-回溯 */queen[row] = -1;}}public void display(){for(int i=0; i<8; i++){int inner;for(inner=0; inner<queen[i]; inner++)System.out.print("0");System.out.print("#");for(inner=queen[i]+1; inner<8; inner++)System.out.print("0");System.out.print("\n");}System.out.println("==========================");}public int getTotal(){return total;}public static void main(String[] args){EightQueen eightQueen = new EightQueen();eightQueen.findQueen(0);int total = eightQueen.getTotal();System.out.println("total is --> " + total);}}


0 0