第五组回溯算法(N皇后排列方法问题)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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);