第五组回溯算法(N皇后排列方法问题)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实训一

N皇后排列方法问题的回溯算法与实现

一、设计目的

1)掌握N皇后排列方法问题的回溯算法;

2)进一步掌握回溯算法的基本思想和算法设计方法;

二、设计内容

1.任务描述

1)算法简介

回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再

走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

2)N皇后排列方法问题简介

在N*N格的棋盘上放置彼此不受攻击的N个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.N后问题等价于在N*N格的棋盘上放置N个皇后,任何2个皇后不放在同一行或同一列或同一斜线上.

3)设计任务简介

对于回溯类似的问题。首先,要能理解该问题运用到的回溯的概念;其次,根据回溯相关的基本思想,找出相应的数学公式;最后,进行程序的设计和编写。

利用回溯的基本思想和计算步骤,有助于我们解决生活中遇到的各种数学问题。

4)问题分析

由于这是一个平面上棋子布局处理问题,因此,我们可以将问题看成是一个二维数组问题。给八个皇后分别编号为1,2,…,8,其中第i个皇后放置在第i行上,并这就解决了不同皇后分别摆放在

不同列的问题,这样又可以把问题简化为一个一维数组的问题,假设用一维数组x[i]来存放皇后所放

置的列,对于第i个皇后,假设它存放在x[i]列上,则对应的x数组应满足如下的条件:[2]

1)因为一共只有8列,故x[i]的取值只能取1到8之间的数。

2)因为不同的皇后只能粗放在不同的列上,则对于任意的i和j,应满足如果i!=j,则x[i]!=x[j]

3)因为不同的皇后不能存放在同一对角线上,故连接两个皇后的直线的斜率应不能等于正负1,而

连接任意第i个皇后和第j个皇后(i与j不同)的直线的斜率的计算公式为:(x[i]-x[j])/(i-j),

即(x[i]-x[j])/(i-j)!=±1,即:|x[i]-x[j]|!=| i-j |

N皇后排列方法问题的表示方案

2.递推过程的抽象描述

本设计采用前向或后向递推公式。用自然语言、伪程序设计语言或流程图等形式针对N皇后排列方法问题的求解(抽象地)描述递推过程……

3.解题思路

4.主要数据类型与变量

Backtrack (int t)//递归调用,回溯法

int nQueen(int n)//皇后排列的方法

int n;//皇后个数

5.算法或程序模块

class Queen

{

friend int nQueen(int);

private:

bool Place(int k);

void Backtrack(int t);

int n,

*x;

long sum;

};

bool Queen::Place(int k)

{

for (int j=1; j

if ((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k])) return false;

return true;

}

void Queen::Backtrack (int t)

{

if (t>n)

sum++;

else

for (int i=1;i<=n;i++)

{

x[t]=i;

if (Place(t)) Backtrack(t+1);

}

}

int nQueen(int n)

{

Queen X;

X.n=n;

X.sum=0;

int*p=new int[n+1];

for(int i=0;i<=n;i++)

p[i]=0;

X.x=p;

X.Backtrack(1);

delete[]p;

return X.sum;

}

三、测试

1.方案

描述测试方案、测试模块、测试数据实例(文字数据、图或表等形式)……

2.结果

四、总结与讨论

通过构造函数,利用回溯思想编写代码,利用回溯的基本思想和计算步骤,有助于我们解决生活中遇到的各种数学问题。

附:程序模块的源代码

#include

#include

class Queen

{

friend int nQueen(int);

private:

bool Place(int k);

void Backtrack(int t);

int n,

*x;

long sum;

};

bool Queen::Place(int k)

{

for (int j=1; j

if ((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k])) return false;

return true;

}

void Queen::Backtrack (int t)

{

if (t>n)

sum++;

else

for (int i=1;i<=n;i++)

{

x[t]=i;

if (Place(t)) Backtrack(t+1);

相关文档
最新文档