回溯法——八皇后问题【通俗易懂】
2016-12-07 21:50
211 查看
回溯法——八皇后问题【通俗易懂】
因为最近在学习算法,所以今天在这里对回溯法中的八皇后问题,进行一下归纳和总结,真的是用不能再通俗的语言去解释了,看不懂请自绝与人民。一、基本定义
回溯法(back track method)是在包含问题的所有可能解的解空间树中,从根结点出发,按照深度优先的策略进行搜索,对于解空间树的某个结点,若满足约束条件,则进入该子树继续搜索,否则将以该结点为根结点的子树进行剪枝。
二、适用范围
可避免搜索所有的可能解,适用于求解组合数较大的问题。
三、八皇后问题
问题:在8 x 8的棋盘上摆放8个皇后,而且八个皇后中的任意两个是不能处于同一行、同一列、或同一斜线上。
【分析】
在8 x 8的棋盘上面放置8个皇后,而且还要不在不同一行和不在同一列,不在同一斜线上,所以每行肯定是得放一个,但是位置就有好多的可能,只要满足上面的要求即可。
设棋盘是一个8 x 8矩阵,皇后i和皇后j的摆放位置分别为(i,Xi)和(j,Xj),要想这些皇后不在同一条斜线上,则需要这两个坐标点的斜率不等于 1 或 - 1。
也就是满足|Xj —Xi | ≠ |j – i|
这里采用迭代法解决八皇后问题,迭代就是循环代码中参与运算的变量同时是保存结果的变量,当前保存的结果作为下一次循环计算的初始值。
迭代的代表性例子:实数累加
int v=1;
for(i=2;i<=100;i++)
{
v=v+i; //1 ——100的累加
}
【具体步骤】
1、这里的八个皇后用k = 0,1,2,3,4,5,6,7来表示。
2、第一个皇后放在8 x 8矩阵的(0 , 0)位置,也就是k = 0 ,x[k] = 0 ,这里的k表示行和皇后k,x[k]表示列。
3、放完第一个皇后之后,就要放置第二个皇后,因为不能在同一行,所以第二个皇后肯定在第二行放,这个时候到底在哪一列还没有确定。
4、在确定第二个皇后到底在哪一列的时候,就要用到一个判断函数,这个函数主要是确定皇后不在同一列和同一斜线上。
check(int k),检查皇后k是否会发生冲突。 int check(int k){ //查看k皇后是否满足约束条件 for(int i=0;i<k;i++) if (x[i]==x[k] || abs(x[i]-x[k]) ==abs(i-k)) //满足不在同一条斜线和同一列 return 1; return 0; }
5、若发生了冲突【即皇后在同一列或同一斜线上】,就x[k]++,一直找到不发生冲突的位置或越界。
6、在找到皇后的位置之后,要先判断一下是否皇后都找到了合适的位置。
7、若还有剩余的皇后或发生越界,则分情况处理,若是还有剩余的皇后,则k = k+1,摆放下一个皇后,若是发生越界,则说明需要回溯,则x[k] = -1 ,k = k – 1
八皇后问题C++代码:
#include<iostream> using namespace std; #include<stdlib.h> static int *x; //用x数组来存放解向量 static int sum; //用sum变量来记录有几个解 int check(int k){ //查看k皇后是否满足约束条件 for(int i=0;i<k;i++) if (x[i]==x[k] || abs(x[i]-x[k]) ==abs(i-k)) //满足不在同一条斜线和同一列 return 1; return 0; } void queen(int n){ int k = 0; //从 皇后0 开始放 sum = 0; while(k>=0){ x[k]++; //摆放第k个皇后(第一次摆放皇后0) while(x[k]<n && check(k) == 1) //对皇后k进行检测,直到不发生冲突或x[k]越界 x[k]++; //检测下一列 if(x[k]<n && k == n-1) { for(int i =0;i<n;i++) cout<<x[i]+1<<" "; cout<<endl; sum++; } if(x[k]<n && k<n-1) //若皇后还没有摆放完,就摆放下一个皇后k = k+1 k++; else //否则就是发生了越界,要进行回溯 { x[k]=-1; k--; } } if(sum == 0) cout<<"无解"<<endl; } int main(){ int n =8; x = new int[n+1]; for(int i=0;i<n;i++){ x[i] = -1; } queen(n); cout<<"一共解的个数为 :"<<sum<<endl; return 0; }
相关文章推荐
- 八皇后问题 回溯递归 C语言版
- 回溯法解八皇后问题
- 八皇后问题 --回溯
- 利用回溯的八皇后问题
- Queen 八皇后问题 回溯经典解法
- GDI+学习(7) 八皇后问题回溯算法演示系统
- 八皇后问题 DFS,回溯剪枝 //http://poj.grids.cn/practice/2698
- 八皇后问题(递归、非递归——回溯)
- C# 用回溯递归解决“八皇后”问题
- 八皇后问题、N皇后问题回溯法详解
- 【算法复习二】八皇后问题 ---- 回溯
- 【算法复习二】八皇后问题 ---- 回溯
- 回溯法解决八皇后和0,1背包问题和排列问题
- 回溯法-八皇后问题之C实现
- 八皇后问题回溯算法演示系统
- 八皇后问题 C#版本算法 回溯法
- 回溯算法---八皇后问题
- uva 11553 Grid Game (回溯- 类似,比八皇后问题简单)
- 回溯算法之八皇后问题
- C#WPF实现回溯算法解决八皇后问题