算法分析与设计实验报告第六次实验测试结果较小皇后个数结果:递归法较大的皇后个数:迭代法较大的皇后个数:输入较大的皇后个数15:输入皇后个数是16时:附录:完整代码(回溯法)//回溯算法 递归回溯 n 皇后问题#include <iostream>#include <time.h>#include <iomanip>#include "math.h"using namespace std;class Queen当输入的皇后个数是20时:运行了一个上午都没有出结果,所以果断放弃了。
实验分析在上述的实验结果中: (1) 我们可以观察到输出皇后排序结果与不输出结果,只输出解的个数是有差距的。
(2) 而且通过对比递归与迭代两种不同的实现方法,发现情况是基本相同的,时间上并没有什么太大的差距,但是相对的迭代会稍微快一点点。
(3) 然后对比输入较大的皇后个数之后,仅仅一个皇后之差就会使得时间上相差很大,如15个皇后的时候所用的时间是280.102,而当皇后个数是16时,所用的时间是2153.463,从而我们可以看出n 皇后问题的时间复杂度是指数级的,从而n 皇后问题确实是NP 问题。
实验心得Dijkstra 算法在之前的数据结构中就学过,在当时只是学过这种思想,并没有去深思这种思想其背后到底是一种怎样的思想在里面。
后来经过本门课的学习,对于贪心算法有了更深刻的了解,也知道了如何利用贪心算法去解决问题。
最开心的是经过一定时间的练习,我的编程能力有了一定的提高,之前看见就很头疼的问题,现在也能静下心来去思考,而且实现Dijkstra 算法也可以通过一定程度的思考也能写出来了,感觉还是很开心的。
Dijkstra 算法求单源最短路径在很多地方都有应用,经过一次又一次的练习,终于能好好的掌握这一算法了,还是希望不要那么快忘记啊。
实验得分 助教签名{friend int nQueen(int); //定义友元函数,可以访问私有数据private:bool Place(int k); //判断该位置是否可用的函数void Backtrack(int t); //定义回溯函数int n; //皇后个数int *x; //当前解long sum; //当前已找到的可行方案数};int main(){int m,n;for(int i=1;i<=1;i++){cout<<"请输入皇后的个数:"; //输入皇后个数cin>>n;cout<<"皇后问题的解为:"<<endl;clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();m=nQueen(n); //调用求解的函数cout<<n<<"皇后问题共有";cout<<m<<"个不同的解!"<<endl; //输出结果end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间cout<<endl;}system("pause");return 0;}bool Queen::Place(int k)//传入行号{for(int j=1;j<k;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++;/*for(int i=1;i<=n;i++) //输出皇后排列的解{cout<<x[i]<<" ";}cout<<endl;*/}else{//回溯探索第i行的每一列是否有元素满足要求for(int i=1;i<=n;i++){x[t]=i;if(Place(t)){Backtrack(t+1);}}}}int nQueen(int n){Queen X; //定义Queen类的对象X//初始化XX.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;//输出解的个数}完整代码(回溯法)//回溯算法迭代回溯 n皇后问题#include<iostream>#include<time.h>#include<iomanip>#include"math.h"using namespace std;class Queen{friend int nQueen(int); //定义友元函数private:bool Place(int k); //定义位置是否可用的判断函数void Backtrack(void); //定义回溯函数int n; // 皇后个数int *x; // 当前解long sum; // 当前已找到的可行方案数};int main(){int n,m;for(int i=1;i<=1;i++){cout<<"请输入皇后的个数:";cin>>n;cout<<n<<"皇后问题的解为:"<<endl;clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();m=nQueen(n); //调用求解皇后问题的函数cout<<n<<"皇后问题共有";cout<<m<<"个不同的解!"<<endl;end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK);//显示运行时间cout<<endl;}system("pause");return 0;}bool Queen::Place(int k){for (int j=1;j<k;j++){if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k])) //如果两个皇后在同一斜线或者在同一列上,说明冲突,该位置不可用{return false;}}return true;}void Queen::Backtrack() //迭代法实现回溯函数{x[1] = 0;int k = 1;while(k>0){x[k] += 1; //先将皇后放在第一列的位置上while((x[k]<=n)&&!(Place(k))) //寻找能够放置皇后的位置{x[k] += 1;}if(x[k]<=n) //找到位置{if(k == n) //如果寻找结束输出结果{/*for (int i=1;i<=n;i++){cout<<x[i]<<" ";}cout<<endl; */sum++;}else//没有结束则找下一行{k++;x[k]=0;}}else//没有找到合适的位置则回溯 { k--; }}}int nQueen(int n){Queen X; //定义Queen类的对象X //初始化XX.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();delete []p;return X.sum; //返回不同解的个数}。