第一篇:回溯法之N皇后问题(C语言)
//回溯法之N皇后问题
当N>10,就有点抽了~~ /*结果前total行每行均为一种放法,表示第i行摆放皇后的列位置,第total+1行,输出total*/ #include
int n,stack[100];
//存当前路径 int total;
//路径数
void make(int l)
//递归搜索以stack[l]为初结点的所有路径 {
int i,j;
//子结点个数
if(l==n+1)
{
total=total+1;
//路径数+1
for(i=1;i<=n;i++)
printf(“%-3d”,stack[i]);//输出第i行皇后的列位置stack[i]
printf(“n”);
exit;
//回溯(若试题仅要求一条路径,则exit改为halt即可)
}
for(i=1;i<=n;i++)
{
stack[l]=i;//算符i作用于生成stack[l-1]产生子状态stack[l];
if(!att(l,i))
make(l+1);
}
//再无算符可用,回溯
}
int att(int l,int i){
int k;
for(k=1;k if(abs(l-k)==abs(stack[k]-i)||i==stack[k])return 1; return 0;} int main(){ printf(“N=”); scanf(“%d”,&n); total=0;//路径数初始化为0 make(1); //从结点1出发,递归搜索所有的路径 printf(“%dn”,total); system(“pause”); return 0;} 由回溯法的算法流程可以看出,除非边界条件设置不当而导致死循环外,回溯法一般是不会产生内存溢出的。但是,回溯法亦有其致命的弱点——时间效率比数学解析法低。为了改善其时效,我们可以从下述几个方面考虑优化: 1、递归时对尚待搜索的信息进行预处理,减少搜索量; 2、尽可能减少分支(解答树的次数); 3、增加约束条件,使其在保证出解的前提下尽可能“苛刻”; 4、在约束条件中设置限定搜索层次的槛值。 人工智能课程设计报告 课 程:人工智能课程设计报告 班 级: 姓 名: 学 号: 指导教师:赵曼 2015年11月 人工智能课程设计报告 人工智能课程设计报告 课程背景 人工智能(Artificial Intelligence),英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器,该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等。人工智能从诞生以来,理论和技术日益成熟,应用领域也不断扩大,可以设想,未来人工智能带来的科技产品,将会是人类智慧的“容器”。 人工智能是对人的意识、思维的信息过程的模拟。人工智能不是人的智能,但能像人那样思考、也可能超过人的智能。 人工智能是一门极富挑战性的科学,从事这项工作的人必须懂得计算机知识,心理学和哲学。人工智能是包括十分广泛的科学,它由不同的领域组成,如机器学习,计算机视觉等等,总的说来,人工智能研究的一个主要目标是使机器能够胜任一些通常需要人类智能才能完成的复杂工作。但不同的时代、不同的人对这种“复杂工作”的理解是不同的。 人工智能是计算机学科的一个分支,二十世纪七十年代以来被称为世界三大尖端技术之一(空间技术、能源技术、人工智能)。也被认为是二十一世纪三大尖端技术(基因工程、纳米科学、人工智能)之一。这是因为近三十年来它获得了迅速的发展,在很多学科领域都获得了广泛应用,并取得了丰硕的成果,人工智能已逐步成为一个独立的分支,无论在理论和实践上都已自成一个系统。 人工智能是研究使计算机来模拟人的某些思维过程和智能行为(如学习、推理、思考、规划等)的学科,主要包括计算机实现智能的原理、制造类似于人脑智能的计算机,使计算机能实现更高层次的应用。人工智能将涉及到计算机科学、心理学、哲学和语言学等学科。可以说几乎是自然科学和社会科学的所有学科,其范围已远远超出了计算机科学的范畴,人工智能与思维科学的关系是实践和理论的关系,人工智能是处于思维科学的技术应用层次,是它的一个应用分支。从思维观点看,人工智能不仅限于逻辑思维,要考虑形象思维、灵感思维才能促进人工智能的突破性的发展,数学常被认为是多种学科的基础科学,数学也进入语言、思维领域,人工智能学科也必须借用数学工具,数学不仅在标准逻辑、模糊数学等范围发挥作用,数学进入人工智能学科,它们将互相促进而更快地发展。 人工智能课程设计报告 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.数据结构 使用数组结构存储相关数据 一维数组: t + n] == 1||rd[i + t] == 1)continue; //没有冲突 ver[i] = 1;ru[i 人工智能课程设计报告 } } //后退处理 rd[i + t] = 0;ru[i1;i++){ } cout << endl;*/ cout << “row:” << i << “ col:” << this->ChromosomeMatrix[i][0] << endl;g = 1;if(DisplayAllAnsures)this->FillArea(k);this->CostMatrix[k] = this->CostFunc(k);bool DisplayAllAnsures=PrintChessBoard;//是否输出所有棋盘结果 int g = 0, num = 0; //逐个检查第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;+ cdiag[GetC(row, optimal_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(){ } //最终用户调用函数,numOfQueens为输入皇后数,PrintChessBoard判断是否输出棋盘表示 int CSP_Queens::CSPAlgorithms(bool PrintChessBord){ srand((unsigned)time(NULL));Init();if(Qualify()){//运气很好,初始化后就满足终止条件 } bool end = false;while(!end){ for(int i = 0;i < N;i++){ if(Adjust_row(i)){ end = true;if(PrintChessBord)Print_result();return 0;for(int i = 0;i < N;i++){ } return true;if(col[R[i]]!= 1 || } pdiag[GetP(i, R[i])]!= 1 || cdiag[GetC(i, R[i])]!= 1){ return false; 人工智能课程设计报告 2.遗传算法 3.CSP最小冲突算法 人工智能课程设计报告 总的来说,回溯在n值很小时,效率很高,但其求解范围很小,超过35基本就解不出来,遗传算法求解范围适中。在n值很大(>100)时,前两者都不能再解决,此时,CSP最小冲突法的效率最高,且与n值没有必然的联系。 总结 通过此次课程实习不仅大大加深了我对几种经典搜索算法的理解,而且帮助我很好的复习了队列、堆栈、图、文件读写这几部分的内容,使我对几种基本的数据结构类型的运用更加熟练。在解决这些问题的过程中我不但很好的巩固了数据结构的相关知识,而且提高了编程及程序调试能力,增强了自己编程的信心。 总之,在这次课程实习过程中我是实实在在学到了一些课堂上学不到的东西,同时也提高了实践能力。同时在这个过程中也暴露了自己的不少问题,在今后的学习过程成也会更加有针对性。最后还要感谢老师的悉心指导,解答我编程过程中的疑问、指出我程序中的不足,及提出可行的解决方法,让我的程序的功能更加完善。 CSP算法源代码: //CSPAlgorithms.h #pragma once class CSP_Queens { public: //构造函数,numOfQueens为输入皇后数,CSP_Queens(int numOfQueens);~CSP_Queens(); private: //row[i]表示当前摆放方式下第i行的皇后数,int *row;//col[i]表示当前摆放方式下第i列的皇后冲突数 int *col;int N;//放置N个皇后在N*N棋盘上 //从左上到右下的对角线上row-col值是相同的,但是这个值有可能是负值,最小为 12],2*N-1条,作为对角线编号 //R[]用来存储皇后放置位置,R[row] = col表示(row,col)处,即“第row行第col列”//cdiag[i]表示编号为i的对角线上的皇后数 int *cdiag;//counter diagonal,副对角线 有个皇后 int *R; public: int swap(int &a, int &b); //给定二维矩阵的一个点坐标,返回其对应的左上到右下的对角线编号 int GetP(int row, int col);//给定二维矩阵的一个点坐标,返回其对应的右上到左下的对角线编号 int GetC(int row, int col);//返回begin, begin + 1,..., endbegin个数中的随机的一个 int My_rand(int begin, int end);//左闭右开[begin, end) 人工智能课程设计报告 N = numOfQueens;row = new int[N];col = new int[N];pdiag=new int[2 * N];cdiag=new int[2 * N];R=new int[N];} CSP_Queens::~CSP_Queens(){ if(NULL!= row)delete[]row;if(NULL!= col)delete[]col;if(NULL!= pdiag)delete[]pdiag;if(NULL!= cdiag)delete[]cdiag;if(NULL!= R)delete[]R;} int CSP_Queens::swap(int &a, int &b){ int t = a;a = b;b = t;return 0;} // int CSP_Queens::GetP(int row, int col){ return row1;} int CSP_Queens::GetC(int row, int col){ return row + col;} //返回begin, begin + 1,..., endbegin个数中的随机的一个 int CSP_Queens::My_rand(int begin, int end)//左闭右开[begin, end){ return rand()%(end 人工智能课程设计报告 { } for(int i = begin;i <= end1;i++){ pdiag[i] = 0;cdiag[i] = 0;} //初始化当前棋局的皇后所在位置的各个冲突数 for(int i = 0;i < N;i++){ col[R[i]]++;pdiag[GetP(i, R[i])]++;cdiag[GetC(i, R[i])]++;} //用最小冲突算法调整第row行的皇后的位置(初始化时每行都有一个皇后,调整后仍然在第 + cdiag[GetC(row, optimal_col)] 人工智能课程设计报告 } } //当前点就是最佳点,一切都保持不变 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;} void CSP_Queens::Print_result(){ } cout << “-------结果为:” << endl;cout << endl;for(int j = 0;j < N;j++){ for(int k = 0;k < N;k++){ if(R[j] == k) cout << “Q”; else cout << “+”; cout << “ ”;} cout << endl;} //最终用户调用函数,numOfQueens为输入皇后数,PrintChessBoard判断是否输出棋盘表 人工智能课程设计报告 int N;cin >> N;int time1 = clock();CSP_Queens myQueens(N);myQueens.CSPAlgorithms(end);int time2 = clock();cout << “---” << N << “皇后问题耗时:” << time2 读书的好处 1、行万里路,读万卷书。 2、书山有路勤为径,学海无涯苦作舟。 3、读书破万卷,下笔如有神。 4、我所学到的任何有价值的知识都是由自学中得来的。——达尔文 5、少壮不努力,老大徒悲伤。 6、黑发不知勤学早,白首方悔读书迟。——颜真卿 7、宝剑锋从磨砺出,梅花香自苦寒来。 8、读书要三到:心到、眼到、口到 9、玉不琢、不成器,人不学、不知义。 10、一日无书,百事荒废。——陈寿 11、书是人类进步的阶梯。 12、一日不读口生,一日不写手生。 13、我扑在书上,就像饥饿的人扑在面包上。——高尔基 14、书到用时方恨少、事非经过不知难。——陆游 15、读一本好书,就如同和一个高尚的人在交谈——歌德 16、读一切好书,就是和许多高尚的人谈话。——笛卡儿 17、学习永远不晚。——高尔基 18、少而好学,如日出之阳;壮而好学,如日中之光;志而好学,如炳烛之光。——刘向 19、学而不思则惘,思而不学则殆。——孔子 20、读书给人以快乐、给人以光彩、给人以才干。——培根 关于c语言编程中八皇后问题的设计报告 一、课题的来源及意义 八皇后问题是一个古老而著名的问题,该问题是十九世纪著名的数学家高斯1850年提出的。 在国际象棋中,皇后是最有权利的一个棋子;只要别的棋子在它的同一行或同一列或同一斜线(正斜线或反斜线)上时,它就能把对方棋子吃掉。所以高斯提出了一个问题:在8*8的格的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后都不能处于同一列、同一行、或同一条斜线上面,问共有多少种解法。 到了现代,随着计算机技术的飞速发展,这一古老而有趣的数学游戏问题也自然而然的被搬到了计算机上。运用所学计算机知识来试着解决这个问题是个锻炼和提高我自己编程能力和独立解决问题能力的好机会,可以使我增强信心,为我以后的编程开个好头,故我选择了这个有趣的课题。 二、面对的问题 1)解决冲突问题:这个问题包括了行,列,两条对角线; 列:规定每一列放一个皇后,不会造成列上的冲突; 行:当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态; 2)使用数据结构的知识,用递归法解决问题。 三、需求分析 1、涉及到的知识 本次设计中,用到的主要知识有:递归法的运用,for语句的灵活运用,数据结构中树知识的灵活运用、栈及数组的掌握。 2、软硬件的需求 1)系统要求:winxp以上操作系统; 2)语言平台:tc++或vc++6.0; 3、功能需求 当运行程序时,在屏幕上显示每一种方法八个皇后的相对位置,要用比较直观 的界面显示。 四、概要设计 我的思想是用循环递归循环来实现的,分别一一测试了每一种摆法,并把它拥有的92种变化表现出来。在这个程序中,我的主要思路以及思想是这样的: 1)解决冲突问题: 这个问题包括了行,列,两条对角线; 列:规定每一列放一个皇后,不会造成列上的冲突; 行:当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态; 对角线:对角线有两个方向。在这我把这两条对角线称为:主对角线和从对角线。在同一对角线上的所有点(设下标为(i,j)),要么(i+j)是常数,要么(i-j)是常数。因此,当第I个皇后占领了第J列后,要同时把以(i+j)、(i-j)为下标的标记置为被占领状态。 2)数据结构的实现 而对于数据结构的实现,学生则是着重于: 数组a[I]:a [I]表示第I个皇后放置的列;I的范围:1..8;对角线数组:b[j](主对角线),c[j](从对角线),根据程序的运行,去决定主从对角线是否放入皇后; 五、详细设计和实现 1、算法描述 A、数据初始化。 B、从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领)。如果是,摆放第n个皇后,并宣布占领(记得姚横列竖列斜列一起设置),接着进行递归;如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,发现此时已无法摆放时,便要进行回溯。从问题的某一种可能出发,搜索从这种情况能出发,继续搜索,这种不断“回溯”的寻找解的方法,称为“回溯法”。 C、使用数组实现回溯法的思想。D、当n>8时,便打印出结果。 E、输出函数我使用printf输出,运行形式为:第m种方法为:* * * * * * * * 2、算法流程图 六、代码编写及详细注释 #include void main()/*----------------------------Main:主函数。----------------------------*/ { system(“title 叶青--递归算法八皇后问题 ”);cout<<“ ”<<“八皇后的解法:”< { Output();return;} for(i = 1;i <= QUEENS;i++)//!n还没到8,在第n行的各个行上依次试探。 { Site[n] = i;//!在该行的第i行上放置皇后。 if(IsValid(n))//!如果放置没有冲突,就开始下一行的试探。 Queen(n + 1);}} int IsValid(int n)/*------IsValid:判断第n个皇后放上去之后,是否合法,即是否无冲突。------*/ { int i;for(i = 0;i < n;i++)//!将第n个皇后的位置依次于前面n-1个皇后的位置比较。 { if(Site[i] == Site[n])//!两个皇后在同一列上,返回0。return 0;if(abs(Site[i]i))//!两个皇后在同一对角线上,返回0。return 0;} return 1;//!没有冲突,返回1。} void Output()/*------------Output:输出一个解,即一种没有冲突的放置方案。------------*/ { int i;printf(“No.%-5d” , ++iCount);//!输出序号。 for(i = 0;i < QUEENS;i++)//!依次输出各个行上的皇后的位置,即所在的列数。printf(“%d ” , Site[i]);printf(“n”);} 七、程序调试 调试过程、步骤及遇到的问题 在完整程序调试时遇到几个小问题,后经细心改正后才把调试工作做完。 例如:当用printf输出时,出现了一些错误,几经调试后,发现原来是缺少了stdio.h这样一个头文件,添加了头文件后, 还出现了一些问题,逻辑错误导致程序死循环或不循环或循环一小部分,但是编译时却没有错误,就是没有正确的输出答案,一开始我也不知道是怎么回事,通过和同学的交流,发现是逻辑错误,经过改正后,程序终于可以运行了.八、运行与测试 运行演示 九、总结 在这次的程序设计,我从中得到了许多的经验以及软件设计的一些新的思路;从这个八皇后问题设计以及分析中,本人从中理解到了数据结构对于计算机软件设计的重要性,它的使用,可以改变一个软件的运行周期,也可以将软件的思路从繁化简,并且都能够通过数据结构的相关引导,将本身以前编程思想进行扩充,发展;这也是在这次课程设计中我所掌握得到的。 但由于我的基本知识还不是那么扎实,也缺乏对软件设计的经验,在这过程中也出现了一些问题,如,八皇后在变成初期由于没真正体会到数据结构中“树”在里面的运用,将程序往大一时c语言的方向发展,不自觉的采用了非递归的算法,结果大大增加了程序的复杂程度。并且也让整个程序的时间复杂度变得更大;在后来学生对数据结构的第六章进行了比较深入的研读,才发现了数据结构树的实际运用的空间是相当的大,并且,通过了重温树的回溯,以及二叉树的遍历,最终将程序进行了一次较大的改造。并且通过思考,再将以前的数组知识加以运用才最终解决了这个问题,整个程序的算法的可看性也有了相当的改进。 以前对数据结构的学习还是具有相当大的意义,它从一个程度上改变了我们的编程思想,如何将一个程序快速而又准备的进行编写,进行编译,都成为了我们思考的重点,也通过这一门课的学习,我们将数据结构的思想带入到了我们以后的编程学习中去。在这个阶段,我也明白了,好的思想,不能提留于字面上的认知,还需要的是平时多练多写一些相关的程序,并且通过修改,加入新的算法去尝试改变自己的一些编程思想。保持更新算法的速度,这才是关键。 我觉得还可以考虑开发N皇后问题,在主界面中添加一个 int型的变量,程序一开始要求输入一个数(确定是几皇后问题),输入后按下 enter 后,输出各种解.主程序与八皇后的求解大体相同.十、参考文献 [1]苏仕华,数据结构课程设计.-北京:机械工业出版社,2005.5 [2]于永彦,赵建洋.课程设计指导书.淮安:江苏淮阴工学院 计算机工程系,2006 [3]刘振安,刘燕君,孙忱.C++语言课程设计.北京:高等教育出版社,2003 [4]陈志泊, 张海燕, 王春玲.Visual C++程序设计.中国铁道出版社 ,2005 [5]吕凤哲,C++语言程序设计(第二版).北京:电子工业出版社,2005 [6]殷人昆,陶永雷等.数据结构(用面向对象方法与C++).北京:清华大学出版社,1999 [7]严蔚敏,吴伟民,数据结构.北京:清华大学出版社,1997 [8]李春葆.数据结构—考研指导.北京:清华大学出版社,2002 [9]陈慧南.数据结构—C++语言描述.北京:人民邮电出版社,2005.03 计算: (1)1+2+3+4+5+6+7+8=? (2)1*1+2*2+3*3+4*4+5*5+6*6+7*7+8*8=? (3)1*1*1+2*2*2+3*3*3+4*4*4+5*5*5+6*6*6+7*7*7+8*8*8=? 程序如下: #include 模型的推广: 计算: 1+2+…+n=? … … 1*1*1*…1+…+n*n*n*…n=? 程序如下: #include 题目计算器软件设计 一、设计要求 用C语言设计出模拟计算器软件,实现计算器的功能。 二、设计内容 1.基本要求: (1)图形显示方式,在DOS环境下画出计算器的图形,能够用鼠标实现操作,能够进行简单的数学计算。 2.提高要求: (1)能够实现键盘和鼠标两种输入方式。 (2)能够保存计算结果。 (3)能够处理括号等运算符。 (4)学生可自动增加新功能模块(视情况可另外加分)。 3.设计报告: 1)写出主要设计思路,图形方式和文本方式的工作原理; 2)画出程序流程图; 3)调试出现的问题及解决方法; 4)提交程序清单。 三、编程重点、难点提示 1.DOS环境下的图形初始化。 2.DOS环境下鼠标的使用方法。1.MOUSE.COM文件; 2.鼠标初始化; 击。 联系方式:谭顺华 电话:6088222,***(V网:61025) QQ:182986843.数字的显示方法。3.鼠标事件的获取,包括鼠标的位置(X,Y),左键或右件,单击或双第二篇:人工智能课程设计报告-n皇后问题解读
第三篇:关于c语言编程中八皇后问题的设计报告
第四篇:C语言关于自然数的和以及自然数n次方的和
第五篇:C语言之计算器软件设计