您的位置:首页 > 其它

回溯法——八皇后问题【通俗易懂】

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  八皇后 算法 搜索