软件学院软件+桥梁工程专业 2 班
一、课程设计(论文)题目八皇后问题
二、课程设计(论文)工作自 2008年 12月 22日起至 2008年 12月 26 日止
三、课程设计(论文) 地点: 信息学院机房
四、课程设计(论文)内容要求:
1.本课程设计的目的
(1)巩固和加深对数据结构基本知识的理解,提高综合运用课程知识的能力。
(2)使学生掌握软件设计的基本内容和设计方法,并培养学生进行规范化软件设计的能力。
(3)使学生掌握使用各种计算机资料和有关参考资料,提高学生进行程序设计的基本能力。
2.课程设计的任务及要求
1)基本要求:
(1)对系统进行功能模块分析、控制模块分析;
(2)系统设计要能完成题目所要求的功能;
(3)编程简练,可用,尽可能的使系统的功能更加完善和全面;
(4)说明书、流程图要清楚;
(5)提高学生的论文写作能力;
(6)特别要求自己完成;
2)创新要求:
在基本要求达到后,可进行创新设计,如改善算法性能、友好的人机界面。
3)课程设计论文编写要求
(1)要按照书稿的规格打印与写课程设计论文
(2)论文包括目录、正文、小结、参考文献、附录等
(3)课程设计论文装订按学校的统一要求完成4)课程设计进度安排
内容天数地点
构思及收集资料 1 图书馆
编码与调试 3 实验室
撰写论文 1 图书馆、实验室
学生签名:
2008 年12 月22 日
课程设计(论文)评审意见
(1)基本算法(20分):优()、良()、中()、一般()、差();(2)设计分析(20分):优()、良()、中()、一般()、差();(3)调试分析(20分):优()、良()、中()、一般()、差();(4)创新设计(20分):优()、良()、中()、一般()、差();(5)总结分析(20分):优()、良()、中()、一般()、差();(6)格式规范性及考勤是否降等级:是()、否()
评阅人:职称:讲师
2008 年12月28日目录
一、需求分析 (1)
二、概要设计 (3)
三、详细设计 (5)
四、调试分析及测试 (8)
五、个人工作及创新 (12)
六、小结 (12)
参考文献 (13)
附录 (13)一、需求分析
八皇后问题是一个古老而著名的问题,该问题是十九世纪著名的数学家高斯1850年提出的,并作了部分解答。高斯在棋盘上放下了八个互不攻击的皇后,他还认为可能有76种不同的放法,这就是有名的“八皇后”问题。
在国际象棋中,皇后是最有权利的一个棋子;只要别的棋子在它的同一行或同一列或同一斜线(正斜线或反斜线)上时,它就能把对方棋子吃掉。
所以高斯提出了一个问题:在8*8的格的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后都不能处于同一列、同一行、或同一条斜线上面,问共有多少种解法。现在我们已经知道八皇后问题有92个解答。
1.1 选题理由
根据自己的知识功底和能力水平择选了八皇后问题.而且随着计算机技术的飞速发展,这一古老而有趣的数学游戏问题也自然而然的被搬到了计算机上。运用所学计算机知识来试着解决这个问题是个锻炼和提高我自己编程能力和解决问题能力的好机会,可以使我增强信心,为我以后的编程开个好头,故我选择了这个有趣的课题。
1.2 涉及到的知识点
本次课程设计中,用到的主要知识有:递归法、回溯法的应用,for语句的灵活运用,数据结构中树知识的灵活运用、栈及数组的掌握.
下面给出八皇后问题回溯算法的伪代码
PlaceQueen(row)
for 第row行的各列colIf 位置(row,col)可以放置皇后
在位置(row,col)放置一个皇后
If(row<9)
PlaceQueen(row+1);
else
成功,打印棋盘
将位置(row,col)上的皇后取走,尝试下一列位置 //回溯
其中回溯法的应用如下:
回溯法也是设计递归过程的一种重要方法,原理或步骤为:试着先把第一个皇后放在棋盘上,然后再放第二个,使两个皇后不会互相攻击,再放第三个皇后,使得她与前面两个皇后都不会互相攻击,依此类推,直至所有的皇后都放上去。如果第七个皇后放上后,第八个皇后已经没有安全的位置可以放置,则试着调试第七个皇后的位置,再尝试第八个皇后有没有安全的位置;如果第七个皇后的所有安全位置都已尝试过了,第八个皇后还是没有安全的位置,则试着调试第六个皇后的位置,重新放置第七、八个皇后的尝试。如此类推,最糟糕的事情就是一直到将第一个皇后的位置进行调整。
1.3 功能要求
当运行程序时,在屏幕上显示每一种方法八个皇后的相对位置,要用比
较直观的界面显示。
进入界面后,就会提示输入字符串的输入形式,在八皇后求解程序中,
只要你选择输出解的格式,选择1则显示为每一列皇后的放置的行数,选
择2则显示的是以矩阵形式形象的显示皇后的放置位置,选择0则退出程序
的调试。在调试结果中,1的位置也就表示了该皇后应该所在的位置,0代表
了空位置。
二、概要设计
2.1 数据结构
1.解数组a,a[i]表示第i个皇后放置的列,范围为1~8。
2. 行冲突标记数组b,b[j]=0 表示第j行空闲,b[j]=1 表示第j行被占领,范围为1~8。
3. 对角线冲突标记数组c、d。c[i-j]=0 表示第(i-j)条对角线空闲,c[i-j]=1 表示第(i-j)条对角线被占领,范围-7~7。d[i+j]=0 表示第(i+j)条对角线空闲,d[i+j]=1 表示第(i+j)条对角线被占领,范围2~16。
2.2 抽象数据类型的定义
Print() //打印每一列皇后的放置的行数以及以矩阵形式形象的显示皇后的放置位置
JudgeQueen1() //递归寻找摆放皇后位子
void main() //主函数调用
2.3 算法流程
1.数据初始化。
2.从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领)。如果是,摆放第n个皇后,并宣布占领(记得姚横列竖列斜列一起设置),接着进行递归;如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,发现此时已无法摆放时,便要进行回溯。从问题的某一种可能出发,搜索从这种情况能出发,继续搜索,这种不断“回溯”的寻找解的方法,称为“回溯法”。
3. 当n>8时,便打印出结果。
其算法流程图如下:
三、详细设计
//定义数组
int a[8] //表示第i个皇后放置的列,范围为1~8。
int b[8] //表示第j行空闲,b[j]=1 表示第j行被占领,范围为1~8 int c[30] //表示第(i-j)条对角线空闲,c[i-j]=1 表示第(i-j)条对角线被占领,范围-7~7
int d[30] //表示第(i+j)条对角线空闲,d[i+j]=1 表示第(i+j)条对角线被占领,范围2~16。
//位置标明法打印
void print1()
{
X++;
cout<<"\No."< cout<<" "<<" "<cout<<"\\n"; } //矩阵表示法打印 void print2() { int t,n; Y++; cout<<"\No."< { n=a[k]; for(t=1;t cout<<"1 "; t++; for(t;t<9;t++) cout<<"0 "; cout<<"\\n\"; } } //回溯递归法摆放皇后 void PlaceQueen1(int i) { int j; for (j=1;j<9;j++) //每个皇后都有8种可能位置 { if ((b[j]==0) &&(c[i+j]==0)&& (d[i-j]==0)) //判断位置是否冲突 { a[i]=j; //摆放皇后 b[j]=1; //宣布占领第J行 c[i+j]=1; //占领两个对角线 d[i-j]=1; if (i<8) PlaceQueen1(i+1); //8个皇后没有摆完,递归摆放下一皇后 else print1(); //完成任务,打印结果 b[j]=0; //回溯 c[i+j]=0; d[i-j]=0; } } } void PlaceQueen2(int i) { int j ,e=1; for (j=1;j<9;j++) { if ((b[j]==0) &&(c[i+j]==0)&& (d[i-j]==0)) a[i]=j; b[j]=1; c[i+j]=1; d[i-j]=1;if (i<8) PlaceQueen2(i+1); else print2(); //打印结果 b[j]=0; //回溯 c[i+j]=0; d[i-j]=0; e++; } } } //调用主函数 void main() { …… cout<<"\\n\\n\** Welcome to EightQueen inquiries software problems **\\n\\n"; for( k=0;k<24;k++) //数据初始化 { b[k]=0; c[k]=0; d[k]=0; } ch='y'; while(ch=='y'||ch=='Y') { cout<<"\\n\ 查询菜单\\n"; cout<<"\\n\******************************************************"; cout<<"\\n\* No.1--------每一行皇后放置的列数的情况*"; cout<<"\\n\* No.2--------视图矩阵形式显示皇后的位置*"; cout<<"\\n\* No.0--------退出*"; cout<<"\\n\******************************************************"; cout<<"\\n\请选择菜单号(No.0--No.2):"; cin>>choice; switch(choice) { case 1: cout<<"\\n\每一行皇后放置的列数的情况\\n\\n";PlaceQueen1(1); //从第1个皇后开始放置 break; case 2: cout<<"\\n\使用回车查看下一种情况\\n\\n";; PlaceQueen2(1); //从第1个皇后开始放置 break; case 0: ch='n'; break; default: cout<<"\\n\\菜单选择错误,请重新输入!\\n"; } } } 四、调试分析及测试 4.1 遇到的问题及解决方法 (1).由于对八个皇后放置的位置不能一次确定,而且前一个皇后的放置位置直接影响着后面的放置位置,使程序调试时要花费不少时间。 (2).本程序有些代码重复出现,显得程序的有些代码看起来很杂乱。但其中最主要的问题是逻辑错误导致程序死循环或不循环或循环一小部分,但是编译时却没有错误,就是没有正确的输出答案。比如说,在void print2()中有for(t;t<9;t++) ,如果赋t=1,则在视图显示法中会出现排序紊乱。类似的还有出现死循环的问题,后在同学和老师的帮助下,经细心改正后才把调试工作做完。 (3). 这里在编写回溯算法时候需要特别注意以下几点: •回溯循环的结束在于第一个皇后被回溯。 •当找到一个解时,需要复制整个棋盘,不然接下来的回溯将破坏已经找到的解。 •找到一个解后,需要在当前皇后的基础上回溯。 •回溯一个皇后时,要对当前的列数进行重置。 一般在编写完核心代码后,需要编写一定的测试代码进行单元测试。否则的话,后面出现的错误的程序代码问题是好难修正的! 4.2 算法的时空分析 该算法的运行时间和和皇后的放置方法成正比,在最好情况下的时间和空间复杂度均为O(1),在最差情况下均为O(n*n),平均情况在它们之间。 4.3 程序模块构架 本程序模块划分比较合理,且利用指数组存储棋盘,操作方便。至于整体的系统架构,为了简单起见,这样的系统可以分成两个模块,第一个模块是负责模拟问题、提供算法,而另外一个模块则致力于窗口演示,是一个窗体应用程序 4.4 算法的改进 这道题可以用非递归循环也可以用递归循环的方法来做,这里我用了后者,其方法是分别一一测试每一种皇后摆法,直到得出正确的答案即所谓的回溯法。 4.5 程序使用说明 (1)本程序的运行环境为DOS操作系统 (2)进入演示程序后即显示文本方式的用户界面 (3)进入界面后,就会提示输入字符串的输入形式,在八皇后求解程序中,只要你选择输出解的格式,选择1则显示为每一列皇后的放置的行数,选择2则显示的是以矩阵形式形象的显示皇后的放置位置,选择3则退出程序的调试。在调试结果中,1的位置也就表示了该皇后应该所在的位置,0代表了空位置。 4.6 测试结果 初步运行界面 位置标明每一行皇后放置的列数 视图矩阵形式显示皇后位置五、个人工作及创新 在本次课程设计的学习过程中,我在其中的最大的收获,就是得到了许多的经验以及软件设计的一些新的思路. 迈着时间的步伐,这次的课程设计也即将结束,但这个学期数据结构的学习还是具有相当大的意义,特别是这次的课程设计,它从一个程度上改变了我们的编程思想,如何将一个程序快速而又准备的进行编写,进行编译,都成为了我思考的重点,也通过这一个学期的学习,我们将数据结构的思想带入到了我们以后的编程学习中去。在这个阶段,我也明白了,好的思想,不能提留于字面上的认知,还需要的是平时多练多写一些相关的程序,并且通过修改,加入新的算法去尝试改变自己的一些编程思想。保持更新算法的速度,这才是关键。比如说,八皇后在变成初期,由于不自觉的采用了非递归的算法,结果大大增加了程序的复杂程度,并且也让整个程序的时间复杂度变得更大. 在这次的八皇后问题中可以用概率算法,也可以采用传统的递归算法,这里我用了后者.而且还用到了回溯法. 回溯法是允许我们在尝试某些选择失败后,能系统的尝试完所有可能的选择。在八皇后问题中越早放置的皇后,她的选择就越多;而越晚放置的皇后,她的选择就越少。八皇后问题和迷宫问题是很相似的,因此,若采用回溯,将能很好很快而且高效率的解决问题。这便是在这次的一些创新之处!当然还可以设计N皇后问题,基本思想不变 六、小结 通过这次的课程设计,我从中得到了许多经验和软件设计的一些新思路;从这个八皇后问题设计以及分析中,本人从中理解到了数据结构对于软件设计的重要性,它的使用,可以改变软件的运行周期,思路从繁化简,并且都能够通过其相关引导,将本身以前编程思想进行扩充,发展.这也是在这次课程设计中我所掌握得到的。 但在这次的课设中也遇了一些问题,如,八皇后在变成初期由于没真正体会到“树”在里面的运用,不自觉的采用了非递归的算法,结果大大增加了程序的复杂程度。并且也让整个程序的时间复杂度变得更大;在重温了树的回溯,以及二叉树的遍历后,最终将程序进行了一次较大的改造。并且通过思考,再将以前的数组知识加以运用才最终解决了这个问题,整个程序的算法的可看性也有了较大的改进。 参考文献 [1].黄晓霞,萧蕴诗.数据挖掘应用研究及展望[J]. 计算机辅助工程. 2001.4:23-29 [2].黄解军,潘和平,万幼川.数据挖掘技术的应用研究.计算机工程与应用, 2003,02:45~48. [3].吕凤哲,C++语言程序设计(第二版).北京:电子工业出版社,2005 [4].耿国华等著,数据结构——C语言描述,西安电子科技大学出版社 [5].苏仕华,数据结构课程设计.-北京:机械工业出版社,2005.5 [6].严蔚敏,吴伟民,数据结构.北京:清华大学出版社,1997 附录 致谢 在这次课程设计中,我遇到了不少问题,包括程序和课程设计的撰写上的,同学老师给了我许多帮助,在此我表示对你们的忠心感谢。同时,学校给了我做课程设计的很好的条件,我才能够顺利的完成,在此,我仅以文字的形式表示忠心感谢,感谢您们对我的帮助。下载本文