回溯法解决N皇后问题
来源:互联网 发布:优化探究官网 编辑:程序博客网 时间:2024/05/17 20:31
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。
问题阐述
N皇后问题:将以上问题改为,对于一个任意的N,求是否存在N皇后问题的摆法?如N=1,4,5,6,7,8,9时,存在摆法。
N皇后问题的解法有全排列和回溯两类,其中全排列可以递归与非递归,回溯也可以递归与非递归。于是共有4种解法,下面采用递归的回溯法解决。
算法思路
由于皇后们不能同行、同列和共对角线,每一行都必定放置了一个皇后。故可以采用回溯法从第0行开始放置,若合理,则继续放下一行,一直放到N-1行,若不合理,则回溯到上一状态,换一个位置继续放置。只要存在一种情况能够放到N-1行,并且该行合理,则表示问题有解。
①放置第一行的皇后,然后进行②
②放置第二行的皇后,先检测自身的方法是否合理。不合理则返回false,回溯到上一状态。合理则继续进行③
③...
一直到最后N-1行成功
程序语言描述
解决算法问题必须用恰当的数据结构将其描述出来,这里用一个一维数组int[] a表示。其中a[i] = j;表示第i行的皇后放在了第j列。(0<=i,j<=N-1)。
Java代码
/* * Created by ping on 2015/8/16. */public class QueensProblem { int N; int a[]; public QueensProblem(int N) { this.N = N; a = new int[N]; for (int y=0;y<N;y++) { a[y] = -1; } } public boolean hasSolution() { for (int y=0;y<N;y++) { if(place(0,y)) { System.out.print(N+"皇后问题的一个解:"); for(int index = 0;index<N;index++) System.out.print(a[index] + " "); System.out.println(""); return true; } } return false; } /*place(i,j)表示把i行的皇后放到第j列*/ public boolean place(int i,int j) { if(i<0||i>=N||j<0|j>=N) return false; a[i] = j; //把第i行的皇后放在第j列 for(int x=0;x<i;x++)//先检测自身是否合理 { for(int y=x+1;y<=i;y++) { if(a[x]==a[y]||Math.abs(a[x]-a[y])==Math.abs(x-y)) { a[i] = -1; //若不合理,则回退 return false; } } } if(i==N-1) return true; //之前漏了这一行!!!如果没有这一行,这违背了递归算法的原则 for (int y=0;y<N;y++) { if(place(i+1,y)) { return true; } } return false; } public static void main(String args[]) { for(int x = 1;x<10;x++) { new QueensProblem(x).hasSolution(); } }}
a.递归总有一个最简单的情况
b.递归总是尝试去解决一个规模更小的问题
c.父问题和子问题不应该有交集
我之前写这个代码的时候调试老是出错,用了1个小时,结果发现是由于违背了条件a,竟然漏掉了对最简单的一种情况的处理。
- 回溯法解决N皇后问题
- 回溯法解决N皇后问题
- 回溯法解决N皇后问题
- 回溯法解决n皇后问题
- 回溯法解决N皇后问题
- 回溯法解决N皇后问题
- 回溯法解决N皇后问题
- 回溯法解决n皇后问题
- java回溯法解决n皇后问题
- 回溯法解决2n皇后(8皇后)问题
- n皇后问题-回溯法
- 【回溯法】n皇后问题
- N皇后问题,回溯法
- 回溯法---n皇后问题
- N皇后问题 【回溯法】
- 【回溯法】n皇后问题
- N皇后问题---回溯法
- N 皇后问题-回溯法
- IIS 下部署WebAPI
- 读《How quitting...》有感
- Android自定义照相机实现(拍照、保存到SD卡,利用Bundle在Acitivity交换数据)
- 大牛们的博客收集
- css滤镜实现页面灰色黑白色效果代码
- 回溯法解决N皇后问题
- 断其一指------异步任务(AsyncTask)
- unity中 拖拽任意的对象
- 【HashMap】深入原理解析
- usaco Healthy Holsteins individual report
- 台大机器学习基石课程之机器学习基本原理和概念
- C++: 继承与派生
- 内存使用技巧及内存池实现(一)
- 存储过程循环添加数据到数据库中