人工智能课程设计报告-n皇后问题解读

合集下载

人工智能课程设计报告(八皇后问题与罗马尼亚问题)

人工智能课程设计报告(八皇后问题与罗马尼亚问题)

人工智能课程设计报告学号:20091000608姓名:王沙沙班级:191091指导老师:赵老师2011年10月14目录1.N皇后问题 (1)需求分析,设计 (1)设计表示 (1)运行结果 (2)用户手册即测试数据 (2)结论 (5)主要算法代码 (5)2罗马尼亚问题 (9)需求分析,设计 (9)设计表示,详细设计 (9)用户手册 (11)运行结果 (11)主要算法代码 (12)3.实习心得 (21)1 N 皇后问题1.问题描述、需求分析在N*N 的棋盘上分布N 个皇后,其中N 个皇后不能在同一行同一列,也不能出现在同一对角线上,此时N 个皇后不会相互攻击。

程序需能手动输入皇后个数,并分别采用回溯法、爬山法、遗传法得出皇后的分布情况,输出皇后的位置即棋盘。

2.设计思想2.1 形式化N 个皇后的位置可用一个N 维数组表示,如921543……,意思是第一个皇后在第一列的第9行。

2.2 程序模块CreatIndividual( )函数用于产生一组表示皇后不在同一行也不再同一列的的一位数组,即产生一组互不相等的0~N 之间的整数,便于快速求解。

IsLegal( )函数用于判断新放置的皇后是否合法,在回溯法中用到。

AttackQueenNum( )用于计算整个棋盘的攻击皇后个数,相当于一个评价函数,在爬山法和遗传法中用到;Find( )回溯法求解函数ClimbHill( )爬山法求解函数;GA( )遗传算法求解函数;(1)函数调用关系图如下:(2)函数接口规格说明:下图中的箭头指向表示为被指向函数所用2.3 详细设计a: CreatIndividual(int *A,int QueenNum):以当时时间为种子循环产生随机数,为了使得产生的随机数都不想等,设计集合S[N]并初始化为0,表示还没有产生一个皇后,当产生的皇后不在S[N]中即S[N]!=1时将S[n]置为1,接着产生下一个皇后,如此循环便产生一组互不相等的值。

n皇后问题实验报告

n皇后问题实验报告

n皇后问题实验报告n皇后问题实验报告引言:n皇后问题是一个经典的数学问题,它要求在一个n×n的棋盘上放置n个皇后,使得它们互相之间不能相互攻击,即任意两个皇后不能处于同一行、同一列或同一对角线上。

本实验旨在通过编程实现n皇后问题的求解,并探索不同算法在解决该问题上的性能差异。

实验步骤及结果:1. 回溯算法的实现与性能分析回溯算法是最常见的解决n皇后问题的方法之一。

它通过递归的方式遍历所有可能的解,并通过剪枝操作来提高效率。

我们首先实现了回溯算法,并对不同规模的问题进行了求解。

在测试中,我们将问题规模设置为4、8、12和16。

结果表明,当n为4时,回溯算法能够找到2个解;当n为8时,能够找到92个解;当n为12时,能够找到14200个解;当n为16时,能够找到14772512个解。

可以看出,随着问题规模的增加,回溯算法的求解时间呈指数级增长。

2. 启发式算法的实现与性能分析为了提高求解效率,我们尝试了一种基于启发式算法的解决方法。

在该方法中,我们使用了遗传算法来搜索解空间。

遗传算法是一种模拟生物进化过程的优化算法,通过进化操作(如选择、交叉和变异)来寻找问题的最优解。

我们将遗传算法应用于n皇后问题,并对不同规模的问题进行了求解。

在测试中,我们将问题规模设置为8、12和16。

结果表明,遗传算法能够在较短的时间内找到问题的一个解。

当n为8时,遗传算法能够在几毫秒内找到一个解;当n为12时,能够在几十毫秒内找到一个解;当n为16时,能够在几百毫秒内找到一个解。

相比之下,回溯算法在同样规模的问题上需要几秒钟甚至更长的时间。

3. 算法性能对比与分析通过对比回溯算法和启发式算法的性能,我们可以看到启发式算法在求解n皇后问题上具有明显的优势。

回溯算法的求解时间随问题规模呈指数级增长,而启发式算法的求解时间相对较短。

这是因为启发式算法通过优化搜索策略,能够更快地找到问题的解。

然而,启发式算法并非没有缺点。

n皇后 实验报告

n皇后 实验报告

n皇后实验报告《n皇后实验报告》引言n皇后问题是一个经典的计算机科学问题,旨在找到一种方法,在n×n的棋盘上放置n个皇后,使得它们互相之间不能攻击到对方。

这个问题不仅在计算机科学领域有着重要的意义,也在数学和逻辑学中有着深远的影响。

在本实验中,我们将探讨不同解决n皇后问题的方法,并对它们进行实验和比较。

实验方法我们选择了几种常见的解决n皇后问题的算法,包括暴力搜索、回溯法、遗传算法和模拟退火算法。

我们使用Python编程语言实现了这些算法,并在不同规模的n值下进行了实验。

我们记录了每种算法的运行时间、内存占用和解的质量,并进行了对比分析。

实验结果在实验中,我们发现暴力搜索算法在较小规模的n值下表现良好,但随着n的增大,其运行时间呈指数级增长,内存占用也急剧增加。

回溯法在中等规模的n值下表现较好,但在大规模n值下也存在性能问题。

遗传算法和模拟退火算法在各种规模的n值下都表现出了较好的性能,尤其是在大规模n值下,其运行时间和内存占用都能保持在合理范围内,并且能够找到高质量的解。

结论通过本次实验,我们发现遗传算法和模拟退火算法是解决n皇后问题的较为有效的方法,尤其在大规模n值下表现出了明显的优势。

这些算法能够在合理的时间内找到高质量的解,对于解决实际问题具有一定的实用性。

同时,我们也意识到在选择解决n皇后问题的算法时,需要根据具体情况来进行选择,不能一概而论。

希望本实验能够为解决n皇后问题提供一些参考和启发。

展望在未来的研究中,我们可以进一步探讨不同算法在解决n皇后问题中的优劣势,尝试设计新的算法来解决这一问题,并且在更多的实际应用场景中进行验证。

同时,我们也可以将这些算法应用到其他类似的组合优化问题中,以期能够找到更加通用和高效的解决方法。

希望通过这些努力,能够为计算机科学和数学领域的发展做出一些贡献。

N皇后问题算法分析实验报告

N皇后问题算法分析实验报告

N皇后问题一、实验内容在n×n格的棋盘上放置彼此不受攻击的n个皇后,按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子,求解可以放置的方法种数。

二、问题分析n后问题等于于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。

即规定每一列放一个皇后,不会造成列上的冲突;当第i行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以i为下标的标记置为被占领状态。

三、实验说明①本次实验中,使用C++语言用回溯法求解N皇后问题。

②输入皇后个数后,输出解以及解的个数。

③时间复杂度为O(n!),利用数组x所含的信息,可将上述回溯法表示成非递归形式,进一步省去O(n)递归栈空间。

四、使用的数据结构回溯法的基本思想是:可以构建出一棵解空间树,通过探索这棵解空间树,可以得到四皇后问题的一种或几种解。

这样的解空间树有四棵在如上图所示的4×4的棋盘上,按列来摆放棋子,首先因为皇后棋子不能在同一列,所以先排除有2个或2个以上的棋子在同一列的情况,所以第一个棋子在第一列有4种摆放方法(第1列第1行,第1列第2行,第1列第3行,第1列第4行),同样第二个棋子在第二列有4种,同样第三个棋子在第三列有4种,同样第四个棋子在第四列有4种,所以进行简单的排除不在同一列的情况后,还有4×4×4×4=256种可能,但是在这256种可能里,依然存在比如棋子在同一行,或在45度斜线上的情况出现。

另一个角度思考,所有的满足四皇后问题的摆放方式一定都存在于这256种情况之中。

简单的理解就是:这256种棋盘局面包含了所有满足4皇后问题的解,但是不包含全部的棋盘局面。

下面是解空间树的示例(以上一段的按列摆放的方式来进行示例讲解),其中第i层的棋盘局面是在第i-1层的棋盘局面演化而来的(1<i<4)上面的图片是以第一个棋子在第一列的第一行而派生出的一个解空间树,最后一层会有64中结局面,同理在以第一个棋子在第一、列的第二/三/四行都分别可以派生出一个解空间树,最后一层都会有64中局面,所以有4棵解空间树,每一棵最终有64个局面,所以一共有4×64=256种局面可以用上面的方法穷举出所有的解,再遍历穷举的所有结果找出所有符合四皇后问题的解,但是这样会很浪费。

n后问题实验报告

n后问题实验报告

n后问题实验报告n后问题实验报告引言:在计算机科学领域中,n后问题是一个经典的数学难题,也是一个常见的回溯算法练习题。

本实验旨在通过编写程序解决n后问题,探索回溯算法的应用和性能。

实验设计:本实验采用Python编程语言,设计一个递归函数来解决n后问题。

通过不断尝试不同的放置方式,直到找到所有合法解。

实验步骤:1. 设计一个函数check(row, col, queens),用于检查当前位置是否可以放置皇后。

2. 设计一个函数solve(n),用于解决n后问题。

在该函数中,使用一个列表queens来存储每一行皇后的位置。

3. 在solve函数中,使用递归的方式进行回溯。

对于每一行,尝试将皇后放置在不同的列上,并调用check函数进行合法性检查。

4. 如果当前位置合法,则将皇后放置在该位置,并递归调用solve函数解决下一行。

5. 如果成功找到一个合法解,则将该解存储在一个列表solutions中。

6. 最后,输出所有的合法解。

实验结果:经过实验,我们成功解决了n后问题,并得到了所有合法解。

以下是一些实验结果的示例:对于n=4的情况,共有两个合法解:- 第一个解:[1, 3, 0, 2]皇后位置:Q - - -- - - Q- Q - -- - Q -- 第二个解:[2, 0, 3, 1]皇后位置:- Q - -Q - - -- - - Q- - Q -对于n=8的情况,共有92个合法解。

由于篇幅限制,我们无法一一列举,但以下是其中一个解的示例:- 解:[0, 4, 7, 5, 2, 6, 1, 3]皇后位置:Q - - - - - - -- - - - Q - - -- - - - - - - Q- - - - - Q - -- - Q - - - - -- - - - - - Q -- Q - - - - - -- - - Q - - - -讨论与结论:通过本次实验,我们成功地解决了n后问题,并得到了所有合法解。

n皇后 实验报告

n皇后 实验报告

n皇后实验报告n皇后实验报告引言:n皇后问题是一个经典的数学问题,其目标是在一个n×n的棋盘上放置n个皇后,使得它们互不攻击。

本实验旨在通过编程实现n皇后问题的解法,并对不同的算法进行性能分析。

实验方法:本实验采用Python语言编写程序,实现了两种常见的解法:回溯法和遗传算法。

回溯法是一种穷举搜索的方法,通过不断尝试每一种可能的放置方式,直到找到满足条件的解;而遗传算法则是通过模拟生物进化的过程,利用选择、交叉和变异等操作逐步优化解的质量。

实验结果:在实验中,我们分别测试了回溯法和遗传算法在不同规模的n皇后问题上的性能表现。

以下是实验结果的总结:1. 回溯法:- 对于规模较小的问题(n<10),回溯法可以在短时间内找到所有解,并输出结果。

- 随着问题规模的增大,回溯法的搜索时间呈指数级增长。

当n=15时,搜索时间已经超过10秒。

- 回溯法在解决大规模问题时,遇到了组合爆炸的问题,无法在合理的时间内得出结果。

2. 遗传算法:- 遗传算法对于规模较小的问题表现不如回溯法,因为其需要较长的时间来找到一个较优解。

- 随着问题规模的增大,遗传算法的性能逐渐超过回溯法。

当n=20时,遗传算法能够在合理的时间内找到一个较优解。

- 遗传算法在解决大规模问题时,相比回溯法有明显的优势,因为其搜索时间增长较慢。

实验讨论:通过对实验结果的分析,我们可以得出以下结论:- 回溯法适用于规模较小的n皇后问题,但在大规模问题上的性能不佳。

- 遗传算法在大规模问题上表现较好,但对于规模较小的问题需要更长的时间来找到较优解。

- 遗传算法的性能受到参数设置的影响,不同的选择、交叉和变异策略可能导致不同的结果。

结论:综上所述,回溯法和遗传算法都是解决n皇后问题的有效方法,但在不同规模的问题上有不同的性能表现。

在实际应用中,我们可以根据问题规模选择合适的算法来求解。

对于规模较小的问题,回溯法可以提供精确的解;而对于大规模问题,遗传算法能够在合理的时间内找到较优解。

八皇后以及N皇后问题分析

八皇后以及N皇后问题分析

⼋皇后以及N皇后问题分析⼋皇后是⼀个经典问题,在8*8的棋盘上放置8个皇后,每⼀⾏不能互相攻击。

因此拓展出 N皇后问题。

下⾯慢慢了解解决这些问题的⽅法:回溯法:回溯算法也叫试探法,它是⼀种系统地搜索问题的解的⽅法。

回溯算法的基本思想是:从⼀条路往前⾛,能进则进,不能进则退回来,换⼀条路再试。

在现实中,有很多问题往往需要我们把其所有可能穷举出来,然后从中找出满⾜某种要求的可能或最优的情况,从⽽得到整个问题的解。

回溯算法就是解决这种问题的“通⽤算法”,有“万能算法”之称。

N皇后问题在N增⼤时就是这样⼀个解空间很⼤的问题,所以⽐较适合⽤这种⽅法求解。

这也是N皇后问题的传统解法,很经典。

算法描述:1. 算法开始,清空棋盘。

当前⾏设为第⼀⾏,当前列设为第⼀列。

2. 在当前⾏,当前列的判断放置皇后是否安全,若不安全,则跳到第四步。

3. 在当前位置上满⾜条件的情况: 在当前位置放⼀个皇后,若当前⾏是最后⼀⾏,记录⼀个解; 若当前⾏不是最后⼀⾏,当前⾏设为下⼀⾏,当前列设为当前⾏的第⼀个待测位置; 若当前⾏是最后⼀⾏,当前列不是最后⼀列,当前列设为下⼀列; 若当前⾏是最后⼀⾏,当前列是最后⼀列,回溯,即清空当前⾏以及以下各⾏的棋盘,然后当前⾏设为上⼀⾏,当前列设为当前⾏的下⼀个待测位置; 以上返回第⼆步。

4.在当前位置上不满⾜条件: 若当前列不是最后⼀列,当前列设为下⼀列,返回到第⼆步; 若当前列是最后⼀列,回溯,即,若当前⾏已经是第⼀⾏了,算法退出,否则,清空当前⾏以及以下各⾏的棋盘,然后,当前⾏设为上⼀⾏,当前列设为当前⾏的下⼀个待测位置,返回第⼆步。

如何判断是否安全:把棋盘存储为⼀个N维数组a[N],数组中第i个元素的值代表第i⾏的皇后位置,这样便可以把问题的空间规模压缩为⼀维O(N),在判断是否冲突时也很简单, ⾸先每⾏只有⼀个皇后,且在数组中只占据⼀个元素的位置,⾏冲突就不存在了, 其次是列冲突,判断⼀下是否有a[i]与当前要放置皇后的列j相等即可。

N皇后问题实验报告C++版

N皇后问题实验报告C++版

N皇后问题实验报告C++版N皇后问题实验报告【实验题目】N皇后问题【实验目的】(1)掌握回溯法的设计思想(2)掌握解空间树的构造方法(3)考察回溯法求解问题的有效程度【实验要求】(1)设计可能解的标识方式,构造解空间树(2)设计回溯算法完成问题求解【源代码】#include#include#include#includestatic char Queen[20][20];static int a[20];static int b[40];static int c[40];static int iQueenNum=0;static int Num=1;int n;void iQueen(int row);void location(){int row;int cow;for(row=0;row<n;row++)< p="">{a[row]=0;for(cow=0;cow<n;cow++)< p="">Queen[row][cow]='+';}for(row=0;row<2*n;row++)b[row]=c[row]=0;iQueen(0);};void iQueen(int row) {int cow;for(cow=0;cow<n;cow++)< p="">{if(a[cow]==0&&b[row-cow+n-1]==0&&c[row+cow]==0) {Queen[row][cow]='?';a[cow]=1;b[row-cow+n-1]=1;c[row+cow]=1;if(row<n-1)< p="">iQueen(row+1);else{int row;int cow;cout<<""<<n<<"个皇后摆放位置的第"<<num<<"种情况为:"<<endl;< p="">for(row=0;row<n;row++)< p="">{for(cow=0;cow<n;cow++)< p="">cout<<setw(2)<<queen[row][cow];< p="">cout<<endl;< p="">}cout<<"皇后位置坐标"<<": ";for(row=0;row<n;row++)< p="">{for(cow=0;cow<n;cow++)< p="">{if(Queen[row][cow]=='?')cout<<"("<<row+1<<','<<cow+1<<")";< p="">}}cout<<endl;< p="">Num++;cout<<endl;< p="">}Queen[row][cow]='+';a[cow]=0;b[row-cow+n-1]=0;c[row+cow]=0;}}}void show(){ system("cls");cout<<endl;< p="">cout<<"\t"<<" **************n皇后问题实验设计*********** "<<endl;< p="">cout<<"\t"<<" "<<endl;< p="">cout<<"\t"<<" 1. 回溯算法 0.退出"<<endl;< p="">cout<<"\t"<<" "<<endl;< p="">cout<<"\t"<<"请选择 1或者0"<<endl;< p=""> }int main(){ system("color 5E");for(;;){ A:show();cout<<endl;< p="">int number;cin>>number;switch(number){case 0: exit(0);case 1: system("cls");cout<<"输入皇后个数(个数大于4):";cin>>n;location();system("pause");goto A;default:cout<<"选择错误,请重新作出选择!"<<=""> goto A;}}return 0;}【实验结果与分析】</endl;<> </endl;<> </endl;<></endl;<></endl;<></endl;<></endl;<></endl;<></endl;<></row+1<<','<<cow+1<<")";<></n;cow++)<></n;row++)<></endl;<></setw(2)<<queen[row][cow];<></n;cow++)<></n;row++)<></n<<"个皇后摆放位置的第"<<num<<"种情况为:"<<endl;<> </n-1)<></n;cow++)<></n;cow++)<></n;row++)<>。

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

课程:人工智能课程设计报告班级:姓名: 学号:指导教师:赵曼2015年11月人工智能课程设计报告课程背景人工智能(Artificial Intelligence),英文缩写为AI。

它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。

人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器,该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等。

人工智能从诞生以来,理论和技术日益成熟,应用领域也不断扩大,可以设想,未来人工智能带来的科技产品,将会是人类智慧的“容器”。

人工智能是对人的意识、思维的信息过程的模拟。

人工智能不是人的智能,但能像人那样思考、也可能超过人的智能。

人工智能是一门极富挑战性的科学,从事这项工作的人必须懂得计算机知识,心理学和哲学。

人工智能是包括十分广泛的科学,它由不同的领域组成,如机器学习,计算机视觉等等,总的说来,人工智能研究的一个主要目标是使机器能够胜任一些通常需要人类智能才能完成的复杂工作。

但不同的时代、不同的人对这种“复杂工作”的理解是不同的。

人工智能是计算机学科的一个分支,二十世纪七十年代以来被称为世界三大尖端技术之一(空间技术、能源技术、人工智能)。

也被认为是二十一世纪三大尖端技术(基因工程、纳米科学、人工智能)之一。

这是因为近三十年来它获得了迅速的发展,在很多学科领域都获得了广泛应用,并取得了丰硕的成果,人工智能已逐步成为一个独立的分支,无论在理论和实践上都已自成一个系统。

人工智能是研究使计算机来模拟人的某些思维过程和智能行为(如学习、推理、思考、规划等)的学科,主要包括计算机实现智能的原理、制造类似于人脑智能的计算机,使计算机能实现更高层次的应用。

人工智能将涉及到计算机科学、心理学、哲学和语言学等学科。

可以说几乎是自然科学和社会科学的所有学科,其范围已远远超出了计算机科学的范畴,人工智能与思维科学的关系是实践和理论的关系,人工智能是处于思维科学的技术应用层次,是它的一个应用分支。

从思维观点看,人工智能不仅限于逻辑思维,要考虑形象思维、灵感思维才能促进人工智能的突破性的发展,数学常被认为是多种学科的基础科学,数学也进入语言、思维领域,人工智能学科也必须借用数学工具,数学不仅在标准逻辑、模糊数学等范围发挥作用,数学进入人工智能学科,它们将互相促进而更快地发展。

题目二:n皇后问题一.问题描述分别用回溯法(递归)、GA算法和CSP的最小冲突法求解n皇后问题。

即如何能够在n×n 的国际象棋棋盘上放置n个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

要求:ⅰ. 输入n,并用运行时间比较几种算法在相同规模的问题时的求解效率,并列表给出结果。

ⅱ. 比较同一算法在n不相同时的运行时间,分析算法的时间复杂性,并列表给出结果。

如八皇后问题的一个解二.设计分析1.算法分析1)回溯法(递归)回溯法解题的一般步骤编辑(1)针对所给问题,定义问题的解空间;(2)确定易于搜索的解空间结构;(3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。

引入一个整型一维数组col[]来存放最终结果,col[i]就表示在棋盘第i列、col[i]行有一个皇后,为了使程序再找完了全部解后回到最初位置,设定col[0]的初值为0,即当回溯到第0列时,说明以求得全部解,结束程序运行。

为了方便算法的实现,引入三个整型数组来表示当前列在三个方向上的状态:a[] a[i]=0表示第i行上还没有皇后;b[] b[i]=0表示第i列反斜线/上没有皇后;c[] c[i]=0表示第i列正斜线\上没有皇后。

棋盘中同一反斜线/上的方格的行号与列号相同;同一正斜线\上的方格的行号与列号之差均相同,这就是判断斜线的依据。

初始时,所有行和斜线上都没有皇后,从第1列的第1行配置第一个皇后开始,在第m列,col[m]行放置了一个合理的皇后,准备考察第m+1列时,在数组a[],b[]和c[]中为第m列,col[m]行的位置设定有皇后的标志;当从第m列回溯到m-1列时,并准备调整第m-1列的皇后配置时,清除在数组a[],b[]和c[]对应位置的值都为1来确定。

2)遗传算法遗传算法的基本运算过程如下:a)初始化:设置进化代数计数器t=0,设置最大进化代数T,随机生成M个个体作为初始群体P(0)。

b)个体评价:计算群体P(t)中各个个体的适应度。

遗传算法遗传算法c)选择运算:将选择算子作用于群体。

选择的目的是把优化的个体直接遗传到下一代或通过配对交叉产生新的个体再遗传到下一代。

选择操作是建立在群体中个体的适应度评估基础上的。

d)交叉运算:将交叉算子作用于群体。

遗传算法中起核心作用的就是交叉算子。

e)变异运算:将变异算子作用于群体。

即是对群体中的个体串的某些基因座上的基因值作变动。

群体P(t)经过选择、交叉、变异运算之后得到下一代群体P(t+1)。

f)终止条件判断:若t=T,则以进化过程中所得到的具有最大适应度个体作为最优解输出,终止计算。

3)csp最小冲突法(1)初始化N个皇后的一个放置,允许有冲突(2)考虑某一行的某个皇后,她可能与x个皇后冲突,然后看看将这个皇后移动到这一行的哪个空位能使得与其冲突的皇后个数最少,就移动到那里。

(也可以考虑列,是等价的)(3)不断执行(2),直到没有冲突为止2.数据结构使用数组结构存储相关数据一维数组:二维数组:3.算法设计1)//回溯搜索void Function1::DFS(int t,bool isShowTime){if (t == n)//说明已经排了n行了(从0开始的),即排列结束了{for (int i = 0; i<n; i++){rec[i] = board[i];}if (! isShowTime )PrintChessBoard();//输出棋局count++;return;}for (int i = 0; i<n; i++){//有冲突if (ver[i] == 1||ru[i - t + n] == 1||rd[i + t] == 1) continue;//没有冲突ver[i] = 1;ru[i - t + n] = 1;rd[i + t] = 1;board[t] = i;DFS(t + 1, isShowTime);//深搜递归//后退处理rd[i + t] = 0;ru[i - t + n] = 0;ver[i] = 0;}return;}2)遗传算法void CGAQueen::PrintChessBoard(bool PrintChessBoard){bool DisplayAllAnsures=PrintChessBoard;//是否输出所有棋盘结果int g = 0, num = 0;InitialPopulation();while (g == 0 && num < this->Iteration){num++;g = 0;for (int k = 0; k < this->Population ; k++){this->FillArea(k);this->CostMatrix[k] = this->CostFunc(k);}this->PopulationSort();if (this->CostMatrix[0] == 0)//已经完成计算g = 1;if (DisplayAllAnsures){PrintTheBestAnsure();/*for (i = 0; i <= ChessBoradLenght - 1; i++){cout << "row:" << i << " col:" << this->ChromosomeMatrix[i][0] << endl;}cout << endl;*/}this->GenerateCrossOverMatrix();this->Mating();this->ApplyMutation();}cout << "实际迭代:" << num <<" 次"<< endl;if (DisplayAllAnsures){cout << "最佳答案为:" << endl;this->PrintTheBestAnsure();}}3)CSP最小冲突算法//用最小冲突算法调整第row行的皇后的位置(初始化时每行都有一个皇后,调整后仍然在第row行)//调整过后check一下看看是否已经没有冲突,如果没有冲突(达到终止状态),返回truebool CSP_Queens::Adjust_row(int row){int cur_col = R[row];int optimal_col = cur_col;//最佳列号,设置为当前列,然后更新//计算总冲突数int min_conflict = col[optimal_col] + pdiag[GetP(row, optimal_col)] - 1 + cdiag[GetC(row, optimal_col)] - 1;//对角线冲突数为当前对角线皇后数减一,三次重叠了//逐个检查第row行的每个位置,看看是否存在冲突数更小的位置for (int i = 0; i < N; i++){if (i == cur_col) continue;int conflict = col[i] + pdiag[GetP(row, i)] + cdiag[GetC(row, i)];if (conflict < min_conflict){min_conflict = conflict;optimal_col = i;}}//如果最佳列位置改变,则皇后移向新的最小冲突位置,要更新col,pdiag,cdiag,if (optimal_col != cur_col){col[cur_col]--;pdiag[GetP(row, cur_col)]--;cdiag[GetC(row, cur_col)]--;col[optimal_col]++;pdiag[GetP(row, optimal_col)]++;cdiag[GetC(row, optimal_col)]++;R[row] = optimal_col;if (col[cur_col] == 1 && col[optimal_col] == 1&& pdiag[GetP(row, optimal_col)] == 1 && cdiag[GetC(row, optimal_col)] == 1) {return Qualify();//qualify相对更耗时,所以只在满足上面基本条件后才检查}}//否则当前点就是最佳点,一切都保持不变return false;//如果都没变的话,肯定不满足终止条件,否则上一次就应该返回true并终止了}//检查冲突bool CSP_Queens::Qualify(){for (int i = 0; i < N; i++){if (col[R[i]] != 1 ||pdiag[GetP(i, R[i])] != 1 ||cdiag[GetC(i, R[i])] != 1) {return false;}}return true;}//最终用户调用函数,numOfQueens为输入皇后数,PrintChessBoard判断是否输出棋盘表示int CSP_Queens::CSPAlgorithms(bool PrintChessBord){srand((unsigned)time(NULL));Init();if (Qualify()) {//运气很好,初始化后就满足终止条件if (PrintChessBord)Print_result();return 0;}bool end = false;while (!end) {for (int i = 0; i < N; i++) {if (Adjust_row(i)) {end = true;break;}}}if (PrintChessBord)Print_result();return 0;}四.运行结果及分析1.递归算法2.遗传算法3.CSP最小冲突算法4.n=4时不同算法的比较5.n=8时不同算法比较结果分析回溯法在皇后数目较小的,很占优势,它的速度非常的快,但随着皇后数目的增加,回溯法显得很不实用,在n=35时,用回溯法已不能较好的解决n皇后问题。

相关文档
最新文档