欢迎来到冰点文库! | 帮助中心 分享价值,成长自我!
冰点文库
全部分类
  • 临时分类>
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • ImageVerifierCode 换一换
    首页 冰点文库 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    人工智能课程设计报告.docx

    • 资源ID:15071356       资源大小:294.16KB        全文页数:33页
    • 资源格式: DOCX        下载积分:5金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要5金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    人工智能课程设计报告.docx

    1、人工智能课程设计报告人工智能课程设计报告学号:*班级:191091* 2011年10月141N皇后问题1 需求分析,设计1 设计表示1运行结果2用户手册即测试数据2结论5主要算法代码52罗马尼亚问题9 需求分析,设计9 设计表示,详细设计9用户手册11 运行结果11 主要算法代码12 3.实习心得211 N皇后问题1问题描述、需求分析 在N*N 的棋盘上分布N个皇后,其中N个皇后不能在同一行同一列,也不能出现在同一对角线上,此时N个皇后不会相互攻击。 程序需能手动输入皇后个数,并分别采用回溯法、爬山法、遗传法得出皇后的分布情况,输出皇后的位置即棋盘。2设计思想2.1 形式化N个皇后的位置可用一

    2、个N维数组表示,如921543,意思是第一个皇后在第一列的第9行。2.2 程序模块CreatIndividual( )函数用于产生一组表示皇后不在同一行也不再同一列的的一位数组,即产生一组互不相等的0N之间的整数,便于快速求解。IsLegal( )函数用于判断新放置的皇后是否合法,在回溯法中用到。AttackQueenNum( )用于计算整个棋盘的攻击皇后个数,相当于一个评价函数,在爬山法和遗传法中用到;Find( )回溯法求解函数ClimbHill( )爬山法求解函数;GA( )遗传算法求解函数;(1)函数调用关系图如下:(2)函数接口规格说明:下图中的箭头指向表示为被指向函数所用2.3 详

    3、细设计a: CreatIndividual(int *A,int QueenNum):以当时时间为种子循环产生随机数,为了使得产生的随机数都不想等,设计集合SN并初始化为0,表示还没有产生一个皇后,当产生的皇后不在SN中即SN!=1时将Sn置为1,接着产生下一个皇后,如此循环便产生一组互不相等的值。b: IsLegal(int *A,int t)此函数用于判断第t列的皇后是否合法,即有没有皇后在同一行、同一列,同一对角线上,并返回true或者false。c: AttackQueenNum(int *A,int QueenNum)循环调用IsLegal()函数对攻击数进行累加并返回其值,此函数作

    4、为棋盘的评价函数。d: Find(int *A,int k,int QueenNum,long beginTime)回溯法求解,因为回溯法的每一层都是for循环,所以不能单纯的用break语句进行控制,因为即使当前层循环停止了,程序还会继续执行上一层的循环,所以将起始时间作为参数进行传递,以便求出算法执行时间,然后用exit(0)语句终止程序,所以要将回溯法放在其它两个算法的后面执行。e: ClimbHill(int *A,int QueenNum):由于在产生一个棋盘个体的时候所有的皇后就不在同一行同一列,所以在爬山法中只对棋盘的列进行交换,这样即使再怎么交换所有的皇后还是不在同一行同一列,

    5、但在交换的时候需要调用AttackQueenNum( )函数进行棋盘的评价,如果交换前的攻击数大于交换后的攻击数则进行交换,否则与下一列进行交换比较,如此循环直到找出解。f: GA( )3用户手册 运行程序,输入皇后个数N,各种算法得到的皇后分布情况、耗时自动显示;4测试数据及测试结果 分别测试4,20,30,50皇后,测试结果如下:程序运行结果:4皇后运行结果20皇后运行结果如下30皇后运行结果如下:50皇后运行结果如下 由于50皇后的棋盘稍大,这里只给出运行时间结论:根据输入皇后个数递增的运行结果可以看出爬山法的速度是相当快的,在皇后个数比较少时回溯法的速度要快于遗传算法,而当皇后个数比较

    6、多时,回溯法的深度搜索明显慢于遗传算法。主要算法程序代码:1:bool IsLegal(int *A,int t) /判断第t列的皇后位置是否合法 int i; for (i=0;i0 & abs(At-1-At)=1)/然后再判断是否与相邻前一列皇后发生冲突 return false; return true;2:void CreatIndividual(int *A,int QueenNum) int i,x;/在产生随机数时使用 int *s=new intQueenNum;/集合,用于产生一组皇后位置 for (i=0;iQueenNum;i+) si=0; srand(unsigne

    7、d)time(NULL);/种子 A0=rand()%QueenNum;/第一列的皇后可以没有限制的产生,所以先产生 sA0=1; for (i=1;iQueenNum;i+) do x=rand()%QueenNum; while (sx=1);/sx=1表示此位置已有皇后,则重新产生新的位置 Ai=x; sAi=1; 3:void Find(int *A,int k,int QueenNum,long beginTime) int i,j; if (k=QueenNum ) for (i=0;iQueenNum;i+) printf( ); for (j=0;jQueenNum;j+) i

    8、f (Aj=i) printf(# ); else printf(O ); printf(n); long endTime = clock();/获得结束时间(endTime-beginTime)10000,单位为毫秒 printf(回溯法 %d 皇后耗时: %d msn,QueenNum,endTime-beginTime); exit(0); else for (i=0;iQueenNum;i+) Ak=i; /对Ak从0开始进行赋值,下面再判断所赋的值是否合法,合法的话进行下一列皇后位置的赋值 if (IsLegal(A,k) Find(A,k+1,QueenNum,beginTime)

    9、; /当循环结束时仍然找不到则返回一层,Ak的层数加1 4:int AttackQueenNum(int *A,int QueenNum) int i,CountAttack=0; if (abs(A0-A1)=1) /判断第一列 CountAttack+; for (i=1;iQueenNum-1;i+) /首先判断前面几列同一行有没有皇后 if (abs(Ai-Ai-1)=1) /与前一列是否冲突 CountAttack+; if (abs(Ai-Ai+1)=1) /与后一列是否冲突 CountAttack+; if (abs(AQueenNum-2-AQueenNum-1)=1)/判断最

    10、后一列 CountAttack+; return CountAttack;5:void ClimbHill(int *A,int QueenNum)int i,j,temp,Mark,Count,CountAttack; /Mark用于标记交换的位置 int MinCountAttack;/在选取移动方案时使用 int *SaveTry=new intQueenNum;/存储临时方案,用于比较 CreatIndividual(A,QueenNum); CountAttack=AttackQueenNum(A,QueenNum); MinCountAttack=CountAttack; for

    11、(i=0;iQueenNum;i+) SaveTryi=Ai; while (CountAttack!=0) for (i=0;iQueenNum & MinCountAttack!=0;i+) Mark=-1; MinCountAttack=AttackQueenNum(SaveTry,QueenNum); /在每一列与其他列交换之前MinCountAttack都等于当前的Try的攻击数 for (j=0;jQueenNum & MinCountAttack!=0;j+) if (i!=j) /只与其他列进行交换 temp=SaveTryj; SaveTryj=SaveTryi; SaveT

    12、ryi=temp; Count=AttackQueenNum(SaveTry,QueenNum); if (Count=0) MinCountAttack=Count;/即为0 Mark=j; /记录交换列的位置 break; /如果攻击数位0直接跳出循环 if (CountMinCountAttack) MinCountAttack=Count; Mark=j; /记录交换列的位置 temp=SaveTryj; /再将刚刚交换的位置复原,用于与下一列进行比较,交换两次即达到交换的效果 SaveTryj=SaveTryi; SaveTryi=temp; if (MinCountAttack=0

    13、) break; if (Mark!=-1) temp=SaveTryMark; /再将刚刚交换的位置复原,用于与下一列进行比较,交换两次即达到交换的效果 SaveTryMark=SaveTryi; SaveTryi=temp; CountAttack=AttackQueenNum(SaveTry,QueenNum); for (i=0;iQueenNum;i+) Ai=SaveTryi; /存储存储最终结果2 罗马尼亚问题1需求分析:从文件中读取图和启发函数,分别用Dijkstra、深度优先、广度优先、贪婪算法、A*算法得到从起始点Arad到目标点Bucharest的一条路径,即为罗马尼亚问

    14、题的一个解,在求解的过程中记录扩展节点的个数(用于比较几种算法的优劣),记录每种算法得到的解,即输出每种解得到的条路径。 2设计:2.1 设计思想对于图的存储采用邻接矩阵进行存储,因为此图节点与边比较多(若比较少则采用邻接表结构,此时效率比较高),采用堆栈和队列等进行路径的存储,并且在某条路径走到最大深度都没有发现目标节点时具有返回上一节点的能力(好处:在某条路上找不到时可以进入相邻的一条路径,并不是单纯的返回:索索失败),为了不重复访问同一个节点(此时路径会出现环,导致程序循环执行)利用集合的思想,即将访问过的节点状态置为1没有访问过的置为0,以此来避免路径出现环。2.2 设计表示(1)函数

    15、调用关系图2.3 详细设计 a: Dijkstra( ) 设置集合数组GatherMaxVertices,按照路径长度递增的顺序逐步产生最短路径,并将起始点到其他节点的距离存放到数组distance中,将到每一个节点的最短路径的前一节点存至path数组中,从起始节点Arad开始,将其状态标为1,重复执行如下步骤N-1次,直至所有节点的状态都为1.1)在所有不在集合的顶点中选取选取distancei最小的一个顶点,设置为第u个顶点;2)将选出的终结点序号U并入集合中,即其状态改为1;3)以u作为新考虑的中间点,修改不在集合中的个顶点的distancej值,如果distanceu+G.edgeu,

    16、j distancei则令distancei=distanceu+ G.edgeu,j,同时记下此路径,pathj=u; 在主函数中利用堆栈和path数组将起始节点到目标节点的路径找出来(因为寻找路径时是从目标点向前倒推寻找的,所以先将路径入栈,再出栈得到的既是从起始点到目标点的一条路径)。b: DF_Searth( ) 设置集合数组GatherMaxVertices,采用堆栈寻找路径;首先将起始节点入栈,然后执行如下循环:1)读取栈顶元素,获得栈顶元素的一个邻接点(此节点的状态需是0,即未访问过),在获得邻接顶点的过程中如果发现目标顶点则进栈,退出循环;2)如果此节点未访问过则进栈,并将其状

    17、态标为1;3)如果找不到邻接点则出栈,执行(1);在执行循环的过程中对扩展的节点个数进行计数,并将堆栈中的路径出栈到数组,在主函数中进行输出。c: BF_Searth( ) 设置集合数组GatherMaxVertices,采用队列寻找路径;首先将起始节点入队列,然后执行如下循环:1)出队列,并将出队列的节点入栈(用于保存路径);2)循环获取此节点的邻接顶点(未访问过的,即状态为0的节点)并入队列,状态标为1,在寻找邻接点的过程中如果发现目标节点则退出循环; 3)将每一次出队列的顶点都进栈保存(用于输出路径) 然后执行寻找路径部分:此处再定义一个堆栈,首先将目标点进栈,设此栈为栈2,先前存储出队

    18、列元素的栈设为栈1:1)栈2出栈;2)栈1循环出栈,如果出栈的顶点状态为1并且与当前顶点不在图的同一行,即不相邻,那么由栈1出栈的顶点即为栈2出栈顶点的父节点,将此节点入栈2,执行(1); 最后将栈2中的所有节点出栈即为宽度优先寻找到的一条路径,同样在寻找的过程中记录扩展节点的个数;d: Greedy_Searth( ) 设置集合数组GatherMaxVertices,采用堆栈,首先将起始节点入栈,执行如下循环:1)读出栈顶元素(只读,并不进行出栈操作);2)循环获取此元素的邻接顶点(即其所有的还未访问过的孩子),利用排序找到启发函数值最小的孩子结点,将此孩子节点入栈,状态标为1,执行(1);

    19、3)如果读出的栈顶元素以找不到邻接顶点即孩子,说明此条路径已经走到最大深度处,则出栈(即返回上一层),此时执行(1),因为只对入栈的元素状态值为1,所以返回上一层的时候寻找出所有的邻接顶点,并找出最小值,此时的最小值是次小值(因为最小值那条路不通),这样程序便进入下一条路径的寻找;e: A_Searth( )设置集合数组GatherMaxVertices,采用堆栈,首先将起始节点入栈,执行如下循环:1)读取栈顶元素,获取此节点的所有邻接顶点(即所有孩子),选取实际路程g(N)与启发函数值最小的节点入栈,将其状态标为1,在此过程中如果发现目标顶点则循环结束;2)如果此条路已走到最大深度处则出栈,

    20、寻找下一条路径,执行(1); 在此函数中定义了一个20*3的数组GHFMaxVertices3用于比较f(N)=g(N)+h(N)(作业的表相似,执行过程相同);f: ReadGraphFile( ) 与ReadHFile( )完成文件的读操作,利用fgetc(fp)函数进行一位一位的读,并将读取的数据转换为整数形式进行存储,以供于其他算法的使用,在循环读取文件的过程中注意文件尾的处理。3用户手册 直接运行程序即可得到Dijkstra、深度优先、广度优先、贪婪算法、A*算法得到的解,即根据相应的算法的到从起始节点到目标节点的一条路径。4整体运行结果如下:5主要算法代码如下:/Dijkstra算

    21、法void Dijkstra(AdjMGraph G, int v0, int distance, int path) int n = G.vertices.size; int *s = (int *)malloc(sizeof(int)*n); /集合 int minDis, i, j, u; /初始化 for(i = 0; i n; i+) distancei = G.edgev0i; si = 0; if(i != v0 & distancei MaxWeight) pathi = v0; else pathi = -1; sv0 =1; for(i = 1; i n; i+) minD

    22、is = MaxWeight; for(j = 0; j n; j+) if(sj = 0 & distancej minDis) u = j; minDis = distancej; if(minDis = MaxWeight) return; su = 1; for(j = 0; j n; j+) if(sj = 0 & G.edgeuj MaxWeight & distanceu + G.edgeuj distancej) distancej = distanceu + G.edgeuj; pathj = u; /深度优先搜索void DF_Searth(AdjMGraph G,int

    23、v0,int vg,int path,int *Expand,int *AnswerWay) int i,x,SumExpand=0; int Vertex; /用于寻找目标节点 int GatherMaxVertices;/集合 SeqStack S; StackInitiate (&S); for (i=0;iMaxVertices;i+) Gatheri=0; StackPush(&S,v0); /首先将起始节点入栈 SumExpand+; Gatherv0=1; while(1) StackTop(S,&x); Vertex=GetFirstVex(G,x); /获取第一个临接点 wh

    24、ile (GatherVertex=1) Vertex=GetNextVex(G,x,Vertex); while (Vertex=-1)/此时未找到下一个临接点 StackPop(&S,&x); StackTop(S,&x); Vertex=GetFirstVex(G,x); while (GatherVertex=1) Vertex=GetNextVex(G,x,Vertex); StackPush(&S,Vertex); SumExpand+; GatherVertex=1;/同一条路径上那个不允许出现相同的节点,防止转圈 if (Vertex=vg) break; *Expand=Su

    25、mExpand; *AnswerWay=S.top; if (S.top=0) printf(深度优先搜索失败); else while(StackNotEmpty(S) StackTop(S,&x); pathS.top-1=x; StackPop(&S,&x); /宽度优先搜索void BF_Searth(AdjMGraph G,int v0,int vg,int path,int *Expand,int *AnswerWay) int i,x,y,SumExpand=0; int Vertex; /用于寻找目标节点 int GatherMaxVertices;/集合 SeqStack S

    26、aveQ,LineSave; /SaveQ将出队列的节点全部进栈,LineSave用于保存路径, StackInitiate(&SaveQ); StackInitiate(&LineSave); SeqCQueue Q; QueueInitiate(&Q); for (i=0;iMaxVertices;i+) Gatheri=0; QueueAppend(&Q,v0); /首先将起始节点入队列 SumExpand+; Gatherv0=1; while(1) QueueDelete(&Q,&x); StackPush(&SaveQ,x); /将每一个出队列的结点进行保存 Vertex=GetFirstVex(G,x); /获取第一个临接点 if (Vertex=vg) break; /此时找到目标节点 if (Vertex=-1) printf(宽度优先搜索失败); return; while(Vertex!=-1) /将x的所有邻接顶点入队列 if (GatherVertex=0) /表示还未扩展 QueueAppend(&Q,Vertex); SumExpand+; GatherVertex=1; Vertex=GetNextVex(G,x,Vertex); if (Vert


    注意事项

    本文(人工智能课程设计报告.docx)为本站会员主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2023 冰点文库 网站版权所有

    经营许可证编号:鄂ICP备19020893号-2


    收起
    展开