人工智能课程设计报告精编版Word文档格式.docx
- 文档编号:22504165
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:46
- 大小:259.94KB
人工智能课程设计报告精编版Word文档格式.docx
《人工智能课程设计报告精编版Word文档格式.docx》由会员分享,可在线阅读,更多相关《人工智能课程设计报告精编版Word文档格式.docx(46页珍藏版)》请在冰豆网上搜索。
要求:
ⅰ.输入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)//回溯搜索
voidFunction1:
:
DFS(intt,boolisShowTime)
{
if(t==n)//说明已经排了n行了(从0开始的),即排列结束了
{
for(inti=0;
i<
n;
i++)
{
rec[i]=board[i];
}
if(!
isShowTime)PrintChessBoard();
//输出棋局
count++;
return;
}
for(inti=0;
//有冲突
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)遗传算法
voidCGAQueen:
PrintChessBoard(boolPrintChessBoard)
boolDisplayAllAnsures=PrintChessBoard;
//是否输出所有棋盘结果
intg=0,num=0;
InitialPopulation();
while(g==0&
&
num<
this->
Iteration)
num++;
g=0;
for(intk=0;
k<
Population;
k++)
this->
FillArea(k);
CostMatrix[k]=this->
CostFunc(k);
this->
PopulationSort();
if(this->
CostMatrix[0]==0)//已经完成计算
g=1;
if(DisplayAllAnsures)
PrintTheBestAnsure();
/*for(i=0;
i<
=ChessBoradLenght-1;
{
cout<
<
"
row:
"
<
col:
ChromosomeMatrix[i][0]<
endl;
}
cout<
*/
GenerateCrossOverMatrix();
Mating();
ApplyMutation();
cout<
实际迭代:
次"
if(DisplayAllAnsures)
cout<
最佳答案为:
PrintTheBestAnsure();
3)CSP最小冲突算法
//用最小冲突算法调整第row行的皇后的位置(初始化时每行都有一个皇后,调整后仍然在第row行)
//调整过后check一下看看是否已经没有冲突,如果没有冲突(达到终止状态),返回true
boolCSP_Queens:
Adjust_row(introw)
intcur_col=R[row];
intoptimal_col=cur_col;
//最佳列号,设置为当前列,然后更新
//计算总冲突数
intmin_conflict=col[optimal_col]+pdiag[GetP(row,optimal_col)]-1
+cdiag[GetC(row,optimal_col)]-1;
//对角线冲突数为当前对角线皇后数减一,三次重叠了
//逐个检查第row行的每个位置,看看是否存在冲突数更小的位置
N;
i++)
if(i==cur_col)continue;
intconflict=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){
returnQualify();
//qualify相对更耗时,所以只在满足上面基本条件后才检查
//否则当前点就是最佳点,一切都保持不变
returnfalse;
//如果都没变的话,肯定不满足终止条件,否则上一次就应该返回true并终止了
//检查冲突
Qualify()
i++){
if(col[R[i]]!
=1||
pdiag[GetP(i,R[i])]!
cdiag[GetC(i,R[i])]!
=1){
returnfalse;
returntrue;
//最终用户调用函数,numOfQueens为输入皇后数,PrintChessBoard判断是否输出棋盘表示
intCSP_Queens:
CSPAlgorithms(boolPrintChessBord)
srand((unsigned)time(NULL));
Init();
if(Qualify()){//运气很好,初始化后就满足终止条件
if(PrintChessBord)Print_result();
return0;
boolend=false;
while(!
end){
i++){
if(Adjust_row(i)){
end=true;
break;
if(PrintChessBord)Print_result();
return0;
四.运行结果及分析
1.递归算法
2.遗传算法
3.CSP最小冲突算法
4.n=4时不同算法的比较
5.n=8时不同算法比较
结果分析
回溯法在皇后数目较小的,很占优势,它的速度非常的快,但随着皇后数目的增加,回溯法显得很不实用,在n=35时,用回溯法已不能较好的解决n皇后问题。
遗传算法优点是能很好的处理约束,能很好的跳出局部最优,最终得到全局最优解,全局搜索能力强;
缺点是收敛较慢,局部搜索能力较弱,运行时间中等,且容易受n值的影响。
遗传算法的运行时间在n很小时没有回溯法快,但是随着n值的增加,遗产算法的优点也就显现出来,它能够解决回溯法不能解决的问题。
CSP最小冲突法是一种始终都比较快的算法,它的运行时间与皇后是个数没有必然的联系,而且在n很大时,它显现出来运行时间短,效率高的优势,但它的缺点是会出现山脊、高原,86%的时间会卡住。
总的来说,CSP最小冲突法较简单,也比较快,在皇后的个数较多时体现出来效率最高,处理多约束大规模问题时往往不能得到较好的解。
总的来说,回溯在n值很小时,效率很高,但其求解范围很小,超过35基本就解不出来,遗传算法求解范围适中。
在n值很大(>
100)时,前两者都不能再解决,此时,CSP最小冲突法的效率最高,且与n值没有必然的联系。
总结
通过此次课程实习不仅大大加深了我对几种经典搜索算法的理解,而且帮助我很好的复习了队列、堆栈、图、文件读写这几部分的内容,使我对几种基本的数据结构类型的运用更加熟练。
在解决这些问题的过程中我不但很好的巩固了数据结构的相关知识,而且提高了编程及程序调试能力,增强了自己编程的信心。
总之,在这次课程实习过程中我是实实在在学到了一些课堂上学不到的东西,同时也提高了实践能力。
同时在这个过程中也暴露了自己的不少问题,在今后的学习过程成也会更加有针对性。
最后还要感谢老师的悉心指导,解答我编程过程中的疑问、指出我程序中的不足,及提出可行的解决方法,让我的程序的功能更加完善。
CSP算法源代码:
//CSPAlgorithms.h
#pragmaonce
classCSP_Queens
public:
//构造函数,numOfQueens为输入皇后数,
CSP_Queens(intnumOfQueens);
~CSP_Queens();
private:
//row[i]表示当前摆放方式下第i行的皇后数,
int*row;
//col[i]表示当前摆放方式下第i列的皇后冲突数
int*col;
intN;
//放置N个皇后在N*N棋盘上
//从左上到右下的对角线上row-col值是相同的,但是这个值有可能是负值,最小为-(N-1),
//所以可以做个偏移,统一加上N-1,这样这个值就在[0,2*N-2]范围内,将这个值作为该对角线的编号
//pdiag[i]表示当前摆放方式下编号为i的对角线上的皇后数
int*pdiag;
//principaldiagonal,主对角线,左上到右下(表示和主对角线平行的2N-1条对角线)
//从右上到左下的对角线row+col的值相同,取值范围为[0,2*N-2],2*N-1条,作为对角线编号
//cdiag[i]表示编号为i的对角线上的皇后数
int*cdiag;
//counterdiagonal,副对角线
//R[]用来存储皇后放置位置,R[row]=col表示(row,col)处,即“第row行第col列”有个皇后
int*R;
intswap(int&
a,int&
b);
//给定二维矩阵的一个点坐标,返回其对应的左上到右下的对角线编号
intGetP(introw,intcol);
//给定二维矩阵的一个点坐标,返回其对应的右上到左下的对角线编号
intGetC(introw,intcol);
//返回begin,begin+1,...,end-1这end-begin个数中的随机的一个
intMy_rand(intbegin,intend);
//左闭右开[begin,end)
//原地shuffle算法,算法导论中的randomizeinplace算法
voidRandomize(inta[],intbegin,intend);
//左闭右开
//初始化皇后的摆放,同时初始化row,col,pdiag,cdiag数组
voidInit();
//用最小冲突算法调整第row行的皇后的位置(初始化时每行都有一个皇后,调整后仍然在第row行)
//调整过后check一下看看是否已经没有冲突,如果没有冲突(达到终止状态),返回true
boolAdjust_row(introw);
boolQualify();
voidPrint_result();
//最终用户调用函数PrintChessBoard判断是否输出棋盘表示
intCSPAlgorithms(boolPrintChessBord);
};
//CSPAlgorithms.cpp
#include"
CSPAlgorithms.h"
#include<
cstdio>
cstdlib>
ctime>
#include<
iostream>
usingnamespacestd;
CSP_Queens:
CSP_Queens(intnumOfQueens)
N=numOfQueens;
row=newint[N];
col=newint[N];
pdiag=newint[2*N];
cdiag=newint[2*N];
R=newint[N];
~CSP_Queens()
if(NULL!
=row)delete[]row;
=col)delete[]col;
=pdiag)delete[]pdiag;
=cdiag)delete[]cdiag;
=R)delete[]R;
swap(int&
b)
intt=a;
a=b;
b=t;
//
GetP(introw,intcol)
returnrow-col+N-1;
GetC(introw,intcol)
returnrow+col;
//返回begin,begin+1,...,end-1这end-begin个数中的随机的一个
My_rand(intbegin,intend)//左闭右开[begin,end)
returnrand()%(end-begin)+begin;
//原地shuffle算法,算法导论中的randomizeinplace算法
voidCSP_Queens:
Randomize(inta[],intbegin,intend)//左闭右开
for(inti=begin;
=end-2;
intx=My_rand(i,end);
swap(a[i],a[x]);
//初始化皇后的摆放,同时初始化row,col,pdiag,cdiag数组
Init()
i++){//首先全部安放在主对角线上
R[i]=i;
//下面随机抽取调换两行皇后位置
Randomize(R,0,N);
//初始化N个皇后对应的R数组为0~N-1的一个排列,
//此时即没有任意皇后同列,也没有任何皇后同行
row[i]=1;
//每行恰好一个皇后
col[i]=0;
2*N-1;
pdiag[i]=0;
cdiag[i]=0;
//初始化当前棋局的皇后所在位置的各个冲突数
col[R[i]]++;
pdiag[GetP(i,R[i])]++;
cdiag[GetC(i,R[i])]++;
//对角线冲突数为当前对角线皇后数减一
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 人工智能 课程设计 报告 精编