八皇后问题的最佳解决方案
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3.1 枚举法解决八皇后问题
② 约束条件
不在同一列的表达式为:xi≠xj;
不在同一主对角线上的表达式为:xi-ixj-j;
不在同一负对角线上的表达式为:xi+i≠xj+j.
3.1 枚举法解决八皇后问题
③ 算法描述
Main1( ) {int a[9]; //初始化定义数组 for (x1=1; x1<=8; x1++) //从第一列开始搜索 for (x2=1; x2<=8; x2++) {if ( check(x2,2)=0 ) continue; //如果约束条件满足,则执行下一 个 for 语句,否则当前皇后位置向右移动一位继续检查约束条件 for (x3=1;x3<=8;x3++) {if(check(x3,3)=0) continue; //同上 for (x4=1;x4<=8; x4++) {if (check(x4,4)=0) continue; //同上 for (x5=1; x5<=8; x5++) {if (check(x5,5)=0) continue; //同上 for (x6=1; x6<=8; x6++) {if (check(x6,6)=0) continue;// 同上
3.1 枚举法解决八皇后问题
for(x7=1; x7<=8; x7++) {if (check(x7,7)=0) continue; //同上 for(x8=1; x8<=8; x8++) //同上 {if (check(x8,8)=0) continue; //同上 else //找到了一组解 for(i=1;i<=8;i++) //输出一组满足约束的解 print(xi); } } } } }} } } check(int xi, int n) //该函数是用来判断是否满足约束{ int i; for(i=1;i<=n1;i++)//这里只需要判断前n-1个 if ( abs( xi- xn)=abs(i-n)) or (xi= xn)//判 断是否同一列或者 同一对角线 return(0); return(1); }
3.2
递归回溯法解决八皇后问题
② 算法描述
int a[20],b[20],c[40],d[40]; int n,t,i,j,k; //t记录解的个数,i控制行,j控制列 main( ) { int i, input(n); //输入皇后的个数 for(i=1;i<=n;i++) { b[i]=0;//记录棋盘n个列 c[i+1]=0; c[n+i]=0;//记录棋盘负对角线 d[i]=0; d[n+i-1]=0;//记录棋盘主对角线 } try(1); }
3.2
非递归回溯法解决八皇后问题
3.2
递归回溯法解决八皇后问题
3.1 枚举法解决八皇后问题
3.1枚举算法解决八皇后问题:
①概述:
这是一种最简单的算法,通过八重循环模拟搜 索空间中的88个状态,按深度优先思想,把第1个皇 后放在第1列,然后开始搜索第2到第8个皇后的合理 位置,每个皇后只能在同一行的8个位置存放,每前 进一步检查是否满足约束条件,不满足时,检查下一 个位置,若满足约束条件,开始下一个皇后的合理位 置检查,直到找出8个皇后的所有合理位置(即问题 的全部解)。
2
二 八皇后问题描述:
来自百度文库
八皇后问题描述
八皇后问题:要在8*8的国际象棋棋盘中放八个皇后,使任意 两个皇后都不能互相吃掉。规则:皇后能吃掉同一行、同一列、同 一对角线的任意棋子。 如图2-1为一种方案,求所有的解。:
图 2-1
3 解决八皇后问题常用算法
三 解决八皇后问题常用的算法:
3.1 枚举法解决八皇后问题
3.2 非递归回溯法解决八皇后问题
check(int k)//检查皇后是否满足约束{ int i; for(i=1;i<=k-1;i++) if (abs(a[i]-a[k])=abs(i-k)) or (a[i]=a[k]) return(0); return(1);} output( ) //输出满足该约束下的一组皇后位置 { int i; for(i=1;i<=n;i++) print(a[i]); }
2
算法设计与分析
报告3
算法设计与分析实验报告
八皇后问题的最佳解决方案
内容提要
1
回溯法概述
2
八皇后问题
3 解决八皇后问题常用算法
4
算法分析与总结
1
回溯法概述
一 回溯法
回溯法实际是一个类似枚举的搜索尝试方 法,它的主题思想是在搜索尝试中找问题的 解,当不满足求解条件就”回溯”(返回),尝 试别的路径。回溯算法是尝试搜索算法中最 为基本的一种算法,其采用了一种“走不通就 掉头”的思想,作为其控制结构。本文主要 描述递归回溯与非递归回溯,并用这两个算 法解决经典的“八皇后”问题,找出该问题的 最佳解决方案。
}
4
算法分析与总结
四 算法分析与总结:
①三种算法比较分析: 算法名字 枚举法 时间复 空间复 杂度 杂度 优缺点
优点:简单,易实现。 缺点:局限于皇后个数较少的情况
88
64
非递归回溯法 S(n2)
递归回溯法
O(nn)
4
算法分析与总结
② 算法总结
本文给出了求解八皇后的三种算法:枚举算 法、递归回溯算法和非递归回溯算法,分析了其 执行时间复杂度,并得到了运行结果,得到了从 枚举解答八皇后问题到递归回溯解答N皇后问题 的最佳解决方案。选择递归回溯法解决八皇后乃 至N皇后问题更好,更具实用性。
3.2
递归回溯法解决八皇后问题
try(int i) { int j; for(j=1;j<=n;j++) //j表示列号,第i个皇后有n种可能位置 if (b[j]=0) and (c[i+j]=0) and (d[i-j+n]=0)//判断位置是否冲突 {a[i]=j; //第i行第j列可以摆放编号为i的皇后 b[j]=1; //占领第j列 c[i+j]=1; d[i-j+n]=1; //占领两个对角线 if (i<n) try(i+1); //n个皇后没有摆完,递归摆放下一皇后 else output( ); //完成任务,打印结果 b[j]=0; c[i+j]=0; d[i-j+n]=0; //回溯,清理现场,从低向上回溯 } output( ){ t=t+1;//这里的t只是用来统计满足条件的解的个数 print(t,' '); for( k=1;k<=n;k++) print(a[k],' '); print(“ 换行符”); }
3.2 非递归回溯法解决八皇后问题
3.2非递归回溯解决八皇后问题:
①概述: 算法1的枚举算法可读性很好,但它只 能解决八皇后问题,而不能解决任意的n 皇后问题。因此不是通用的回溯算法。下 面的非递归算法可以说是通用的n皇后问 题算法模型。
3.2 非递归回溯法解决八皇后问题
② 算法描述
t a[20],n; Main2() { input(n); bckdate(n);} //初始化,输入皇后数目 backdate (int n) //该函数是用来寻找满足约束的全部解 { int k; a[1]=0; k=1; //k用来表示第k个皇后 while( k>0 ) {a[k]=a[k]+1; while ((a[k]<=n) and (check(k)=0)) //搜 索第k个皇后位置 a[k]=a[k]+1; if( a[k]<=n) if(k=n ) output(n); //找到一组解/ else {k=k+1; //继续为第k+1个皇后找到位置/ a[k]=0;} //注意下一个皇后一定要从头开始搜索/ else k=k-1; //回溯 } }
3.2
递归回溯法解决八皇后问题
3.3递归回溯解决八皇后问题:
①概述:
对于回溯算法,更方便地是用递归控制方式实现,这种方式也可 以解决任意的n皇后问题,算法的思想同样用深度优先搜索,在不满 足约束条件时及时回溯。 与上面两个算法不同,都是用check()函数来检查当前状态是否 满足约束条件,由于递归调用、回溯的整个过程是非线性的,用 check()函数来检查当前状态是否满足约束条件是不充分的,而 用check()函数(在算法1中说明)来检查当前状态是否满足约束 条件又有太多冗余。 这里,我们 “利用数组记录状态信息”的技巧,用三个数组c,b,d 分别记录棋盘上的n个列、2n-1个主对角线和2n-1个负对角线的占用 情况。