实验6迭代实现物联1301班刘悦08080112Word文档格式.docx
- 文档编号:15798806
- 上传时间:2022-11-16
- 格式:DOCX
- 页数:18
- 大小:237.24KB
实验6迭代实现物联1301班刘悦08080112Word文档格式.docx
《实验6迭代实现物联1301班刘悦08080112Word文档格式.docx》由会员分享,可在线阅读,更多相关《实验6迭代实现物联1301班刘悦08080112Word文档格式.docx(18页珍藏版)》请在冰豆网上搜索。
使用迭代实现回溯法。
从第一行开始放置皇后,第一行从第一列开始放置。
之后放置第二行,与已放置的皇后冲突的位置不再考虑。
之后再放置后面行的皇后,一旦某一行无位置可放,就退回到上一行,选择后面的其他位置进行放置。
之后再重复上面的过程。
一旦到达最后一行,就求得了解,记录这个时候的放置的信息。
实验步骤
1放置第一行的皇后。
2放置后面行的皇后,与已放置的皇后在同一直线、横线、斜线的位置不能放置。
3放置后面的皇后。
一旦某一行无位置可放,就返回到上面一行,选择其他位置放置皇后。
4一旦到达最后一行,意味着找到了一个可行解,就记录这个放置方案。
5重复过程,直至找到所有可能的放置解。
关键代码
/*=================================================================
定义Queen类来存储皇后的信息。
=================================================================*/
classQueen
{
friendintnQueen(int);
private:
boolPlace(intk);
voidBacktrack(void);
intn;
//皇后个数
int*x;
//当前解
longsum;
//当前已找到的可行方案数
};
Place函数进行可行性约束。
若当前的位置已经与之前放置的皇后位置冲突,返回false;
否则返回true。
若两皇后的斜率为-1或1则表示在同一斜线上就冲突,返回false。
*******************************************************************
k表示当前放置的皇后的行数。
x[k]表示第k行皇后放置的列数。
即第k个皇后放在第x[k]列。
=================================================================*/
boolQueen:
:
Place(intk)
for(intj=1;
j<
k;
j++)
//abs(k-j)==abs(x[j]-x[k])时,两皇后在同一斜线上
if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k]))
returnfalse;
returntrue;
}
Backtrack函数迭代求皇后放置的位置。
如果已经放完最后一行,就将放置方案数加一,并将各个皇后放置的位置输出到记事本中
否则,就找一个可以放置的位置,然后进行下一行的放置。
这里使用迭代实现,使用k来记录当前的行数
如果某一行无位置可放,将回溯到前面一行,即k--,选择其他位置放置皇后。
voidQueen:
Backtrack(void)
x[1]=0;
intk=1;
while(k>
0)
{
x[k]+=1;
//第k行的放置皇后为第一列
//如果不满足约束条件就继续找后面一列看是否可放皇后
while((x[k]<
=n)&
&
!
(Place(k)))
x[k]+=1;
//当前行有位置可放
if(x[k]<
=n)
//已经放完最后一行的皇后
if(k==n)
{
sum++;
//找到的放置方案数+1
//将具体放置方案写到记事本文件【N皇后_迭代.txt】中
staticofstreamfout("
N皇后_迭代.txt"
);
fout<
<
"
第"
sum<
种方案:
endl;
for(inti=1;
i<
=n;
i++)
{
for(intj=1;
{
if(j==x[i])
fout<
x"
;
//x表示皇后放置的位置
elsefout<
*"
//*表示没有放置皇后的位置
}
fout<
}
}
//没有放完最后一行
else
k++;
//继续放下一行
x[k]=0;
//下一行刚开始为0位置,这样循环之后+1就可以从第1列开始看
//没有位置可放,就回溯到前面一行
elsek--;
}
nQueen函数进行初始化,并方案数目返回。
主要为调用Backtrack函数。
******************************************************************
n表示皇后数。
intnQueen(intn)
QueenX;
//初始化X
X.n=n;
X.sum=0;
int*p=newint[n+1];
for(inti=0;
p[i]=0;
X.x=p;
//调用函数
X.Backtrack();
//删除动态分配内存
delete[]p;
returnX.sum;
测试结果
Ø
8皇后
记事本中的结果如上所示。
可以看到实现了方案的输出。
8皇后问题的时候,算法的时间不如之前的写过的算法的性能好,这里主要是因为,在算法中实现了将结果写入到记事本中,浪费了很多时间。
9皇后
10皇后
11皇后
12皇后
13皇后
可以清楚的发现,N皇后问题,皇后越多,时间越多,当13皇后的时候这个时间已经非常大了,这里是因为算法实现的过程中要找到所有的情况,要将树全部遍历晚,皇后数目越多的时候树的结点就越多,遍历越慢,所以耗费很长时间。
与前面的递归实现相比,对应的N皇后的时间都差不多的,就是最后13皇后的时候,迭代实现比递归实现慢的很明显。
实验心得
因为前面已经使用递归实现了回溯法求N皇后问题,使用迭代实现的思路与使用递归实现的思路是一样的,代码的大体框架都是类似的,所以编写过程中没有什么大问题。
这里主要是写一下迭代的代码来看一下区别。
写完之后可以发现,其实思路都是一样的。
递归的话,因为只要调用函数自身,传一个层数的参数进去就可以,所以代码显得十分简洁。
但是就我们本身来说,看到一个完全不知道什么编写思路的代码如果使用了递归的话,我们理解起来可能会很有难度。
我个人认为递归的代码实现比较容易出错。
迭代的话,看到代码会很容易读懂,但是会要增加另外的变量来表示到了哪一层,就会使代码显得比较冗长。
就我个人来说,我一般喜欢写递归的实现,因为我是在已知思路的情况下进行代码编写,所以递归实现起来并不难。
实验得分
助教签名
附录:
完整代码
#include<
iostream>
cmath>
fstream>
time.h>
iomanip>
stdlib.h>
usingnamespacestd;
/*============================================================================
============================================================================*/
******************************************************************************
============================================================================*/
*******************************************************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 实现 1301 班刘悦 08080112