




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、人工智能实验题目实验一 图的宽度优先搜索算法实验一、实验目的:熟悉和掌握盲目式搜索的定义和图的搜索算法过程,并利用图的宽度优先搜索算法求解N数码难题,理解求解流程和搜索顺序。二、实验原理:图的宽度优先搜索是一种盲目搜索算法,其特点在于每次把扩展节点过程中产生的新节点插入Open表中的尾部,扩展节点时总是选择Open表中的头节点作为扩展节点。三、实验条件:1 N数码难题演示程序。 (/jpkc/rengongzhineng/index.htm)-人工智能实验2 VC 6.0或Java。三、实验内容:1分别以8数码和15数码为例实际求解图的宽度优先搜索算法。
2、2 画出图的宽度优先搜索算法求解框图。3 分析图的宽度优先搜索算法的特点。四、实验步骤:1 开始演示。进入N数码难题演示程序,可选8数码或者15数码,点击“选择数码”按钮确定。第一次启动后,点击两次“缺省”或者“随机”按钮,才会出现图片。2 点击“缺省棋局”,会产生一个固定的初始节点。点击“随机生成”,会产生任意排列的初始节点。3 算法执行。点击“连续执行”则程序自动搜索求解,并演示每一步结果;点击“单步运行”则每次执行一步求解流程。“运行速度”可自由调节。4 观察运行过程和搜索顺序,理解启发式搜索的原理。在下拉框中选择演示“15数码难题”,点击“选择数码”确定选择;运行15数码难题演示实例。
3、5 算法流程的任一时刻的相关状态,以算法流程高亮、open表、close表、节点静态图、当前扩展节点移动图等5种形式在按钮上方同步显示,便于深入学习理解图的宽度优先搜索算法。6 根据程序运行过程画出图的宽度优先搜索算法框图。五、实验报告要求:1图的宽度优先搜索算法流程图和算法框图。2 根据图的宽度优先搜索算法分析盲目式搜索的特点。实验二 A*算法实验一、实验目的:熟悉和掌握启发式搜索的定义、估价函数和算法过程,并利用A*算法求解N数码难题,理解求解流程和搜索顺序。二、实验原理:A*算法是一种有序搜索算法,其特点在于对估价函数的定义上。对于一般的有序搜索,总是选择f值最小的节点作为扩展节点。因此
4、,f是根据需要找到一条最小代价路径的观点来估算节点的,所以,可考虑每个节点n的估价函数值为两个分量:从起始节点到节点n的代价以及从节点n到达目标节点的代价。三、实验条件:1 N数码难题演示程序。3 VC 6.0或Java。三、实验内容:1 分别以8数码和15数码为例实际求解A*算法。2 画出A*算法求解框图。3 分析估价函数对搜索算法的影响。4 分析A*算法的特点。四、实验步骤:1 开始演示。进入N数码难题演示程序,可选8数码或者15数码,点击“选择数码”按钮确定。第一次启动后,点击两次“缺省”或者“随机”按钮,才会出现图片。2 点击“缺省棋局”,会产生一个固定的初始节点。点击“随机生成”,会
5、产生任意排列的初始节点。3 算法执行。点击“连续执行”则程序自动搜索求解,并演示每一步结果;点击“单步运行”则每次执行一步求解流程。“运行速度”可自由调节。4 观察运行过程和搜索顺序,理解启发式搜索的原理。在下拉框中选择演示“15数码难题”,点击“选择数码”确定选择;运行15数码难题演示实例。5 算法流程的任一时刻的相关状态,以算法流程高亮、open表、close表、节点静态图、当前扩展节点移动图等5种形式在按钮上方同步显示,便于深入学习理解A*算法。6 根据程序运行过程画出A*算法框图。五、实验报告要求:1 A*算法流程图和算法框图。2 试分析估价函数的值对搜索算法速度的影响。3 根据A*算
6、法分析启发式搜索的特点。一、题目说明:(九宫问题)在一个的九宫中有这个数及一个空格随机的摆放在其中的格子里,如图所示。现在要求实现这个问题:将该九宫格调整为如图右图所示的形式。调整的规则是:每次只能将与空格(上、下、或左、右)相邻的一个数字平移到空格中。试编程实现这一问题的求解。(图)二、题目分析:九宫问题是人工智能中的经典难题之一,问题是在方格棋盘中,放格数,剩下的没有放到的为空,每次移动只能是和相邻的空格交换数。程序自动产生问题的初始状态,通过一系列交换动作将其转换成目标排列(如下图到图的转换)。 (图)(图)九宫问题中,程序产生的随机排列转换成目标共有两种可能,而且这两种不可能同时成立,
7、也就是奇数排列和偶数排列。我们可以把一个随机排列的数组从左到右从上到下用一个一维数组表示,如上图我们就可以表示成,其中代表空格。在这个数组中我们首先计算它能够重排列出来的结果,公式就是:(),其中()就是一个数他前面比这个数小的数的个数,为奇数和偶数个有一种解法。那么上面的数组我们就可以解出它的结果。();();();();();();();();是偶数,所以他的重排列就是如图的结果,如果加起来的结果是奇数重排的结果就是如图最右边的排法。三、算法分析九宫问题的求解方法就是交换空格()位置,直至到达目标位置为止。图形表示就是:(图)要想得到最优的就需要使用广度优先搜索,九宫的所以排列有!种,也就
8、是种排法,数据量是非常大的,我使用的广度搜索,需要记住每一个结点的排列形式,要是用数组记录的话会占用很多的内存,我们把数据进行适当的压缩。使用形式保存,压缩形式是每个数字用位表示,这样就是个字节,由于的二进制表示形式,不能用位表示,我使用了一个小技巧就是将表示位,然后用多出来的个字表示所在的位置,就可以用表示了。用移位和或操作将数据逐个移入,比乘法速度要快点。定义了几个结果来存储遍历到了结果和搜索完成后保存最优路径。类结构如下:class CNineGirdpublic:struct PlaceList DWORD Place;PlaceList* Left;PlaceList* Right;
9、 ;struct ScanbufDWORD Place;int ScanID;struct PathListunsigned char Path9;private:PlaceList *m_pPlaceList;Scanbuf *m_pScanbuf;RECT m_rResetButton;RECT m_rAutoButton;public:int m_iPathsize;clock_t m_iTime;UINT m_iStepCount;unsigned char m_iTargetChess9;unsigned char m_iChess9;HWND m_hClientWin;PathLi
10、st *m_pPathList;bool m_bAutoRun;private:inline bool AddTree(DWORD place , PlaceList*& parent);void FreeTree(PlaceList*& parent);inline void ArrayToDword(unsigned char *array , DWORD & data);inline void DwordToArray(DWORD data , unsigned char *array);inline bool MoveChess(unsigned char *array , int w
11、ay);bool EstimateUncoil(unsigned char *array);void GetPath(UINT depth);public:void MoveChess(int way);bool ComputeFeel();void ActiveShaw(HWND hView);void DrawGird(HDC hDC , RECT clientrect);void DrawChess(HDC hDC , RECT clientrect);void Reset();void OnButton(POINT pnt , HWND hView);public:CNineGird(
12、);CNineGird();计算随机随机数组使用了vector模板用random_shuffle(,)函数来打乱数组数据,并计算目标结果是什么。代码:void CNineGird:Reset()if(m_bAutoRun) return;vector vs;int i;for (i = 1 ; i 9 ; i +)vs.push_back(i);vs.push_back(0);random_shuffle(vs.begin(), vs.end(); random_shuffle(vs.begin(), vs.end(); for ( i = 0 ; i 9 ; i +)m_iChessi =
13、vsi;if (!EstimateUncoil(m_iChess)unsigned char array9 = 1,2,3,8,0,4,7,6,5;memcpy(m_iTargetChess , array , 9);elseunsigned char array9 = 1,2,3,4,5,6,7,8,0;memcpy(m_iTargetChess , array , 9);m_iStepCount = 0;数据压缩函数实现:inline void CNineGird:ArrayToDword(unsigned char *array , DWORD& data)unsigned char n
14、ight = 0;for ( int i = 0 ; i 9 ; i +)if (arrayi = 8)night = (unsigned char)i;break;arraynight = 0;data = 0;data = (DWORD)(DWORD)array0 29 | (DWORD)array1 26 | (DWORD)array2 23 | (DWORD)array3 20 | (DWORD)array4 17 | (DWORD)array5 14 | (DWORD)array6 11 | (DWORD)array7 8 | (DWORD)array8 5 | night);arr
15、aynight = 8;解压缩时跟压缩真好相反,解压代码:inline void CNineGird:DwordToArray(DWORD data , unsigned char *array)unsigned char chtem;for ( int i = 0 ; i (32 - (i + 1) * 3) & 0x);arrayi = chtem;chtem = (unsigned char)(data & 0xF);arraychtem = 8;由于可扩展的数据量非常的大,加上我在保存的时候使用的是类型,将每一步数据都记录在一个排序二叉树中,按从小到大从左到有的排列,搜索的时候跟每次搜
16、索将近万次的形式比较快几乎是次方倍,把几个在循环中用到的函数声明为内联函数,并在插入的时候同时搜索插入的数据会不会在树中有重复来加快总体速度。二叉树插入代码:inline bool CNineGird:AddTree(DWORD place , PlaceList*& parent)if (parent = NULL)parent = new PlaceList();parent-Left = parent-Right = NULL;parent-Place = place;return true;if (parent-Place = place)return false;if (parent
17、-Place place)return AddTree(place , parent-Right);return AddTree(place , parent-Left);计算结果是奇数排列还是偶数排列的代码:bool CNineGird:EstimateUncoil(unsigned char *array)int sun = 0;for ( int i = 0 ; i 8 ; i +)for ( int j = 0 ; j 9 ; j +)if (arrayj != 0)if (arrayj = i +1 )break;if (arrayj i + 1)sun+;if (sun % 2 =
18、 0)return true;elsereturn false;移动到空格位的代码比较简单,只要计算是否会移动到框外面就可以了,并在移动的时候顺便计算一下是不是已经是目标结果,这是用来给用户手工移动是给与提示用的,代码:inline bool CNineGird:MoveChess(unsigned char *array , int way)int zero , chang;bool moveok = false;for ( zero = 0 ; zero 9 ; zero +)if (arrayzero = 0)break;POINT pnt;pnt.x = zero % 3;pnt.y
19、= int(zero / 3);switch(way)case 0 : /upif (pnt.y + 1 -1)chang = (pnt.y - 1) * 3 + pnt.x ;arrayzero = arraychang;arraychang = 0;moveok = true;break;case 2 : /leftif (pnt.x + 1 -1)chang = pnt.y * 3 + pnt.x - 1;arrayzero = arraychang;arraychang = 0;moveok = true;break;if (moveok & !m_bAutoRun)m_iStepCo
20、unt + ;DWORD temp1 ,temp2;ArrayToDword(array , temp1);ArrayToDword(m_iTargetChess , temp2);if (temp1 = temp2)MessageBox(NULL , 你真聪明这么快就搞定了! , _ , 0); return moveok;我在进行广度搜索时候,将父结点所在的数组索引记录在子结点中了,所以得到目标排列的时候,我们只要从子结点逆向搜索就可以得到最优搜索路径了。用变量m_iPathsize来记录总步数,具体函数代码:void CNineGird:GetPath(UINT depth)int no
21、w = 0 , maxpos = 100 ;UINT parentid;if (m_pPathList != NULL)delete m_pPathList;m_pPathList = new PathListmaxpos;parentid = m_pScanbufdepth.ScanID;DwordToArray(m_pScanbufdepth.Place , m_pPathList+now.Path);while(parentid != -1)if (now = maxpos)maxpos += 10;PathList * temlist = new PathListmaxpos;memc
22、py(temlist , m_pPathList , sizeof(PathList) * (maxpos - 10);delete m_pPathList;m_pPathList = temlist;DwordToArray(m_pScanbufparentid.Place , m_pPathList+now.Path);parentid = m_pScanbufparentid.ScanID;m_iPathsize = now;动态排列的演示函数最简单了,为了让主窗体有及时刷新的机会,启动了一个线程在需要主窗体刷新的时候,用()函数来暂停一下线程就可以了。代码:unsigned _stdc
23、all MoveChessThread(LPVOID pParam)CNineGird * pGird = (CNineGird *)pParam;RECT rect;pGird-m_iStepCount = 0;:GetClientRect(pGird-m_hClientWin , &rect);for ( int i = pGird-m_iPathsize ; i 0 ; i -)memcpy(pGird-m_iChess , pGird-m_pPathListi.Path , 9);pGird-m_iStepCount +;InvalidateRect( pGird-m_hClientW
24、in , &rect , false);Sleep(300);char msg100;sprintf(msg , _ ! 搞定了!rn计算步骤用时%d毫秒 , pGird-m_iTime);MessageBox(NULL , msg , _ , 0);pGird-m_bAutoRun = false;return 0L;最后介绍一下搜索函数的原理,首先得到源数组,将其转换成型,与目标比较,如果相同完成,不同就交换一下数据和空格位置,加入二叉树,搜索下一个结果,直到没有步可走了,在搜索刚刚搜索到的位置的子位置,这样直到找到目标结果为止,函数:bool CNineGird:ComputeFeel()unsigned char *array = m_iChess;UINT i;const int MAXSIZE = ;unsigned char temparray9;DWORD target , fountain , parent , parentID = 0 , child = 1;ArrayToDword(m_iTargetChess , target);ArrayToDword(array , fountain);if (fountain = target)return f
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 煤矿清巷工技能理论考试题库150题(含答案)
- 物业服务中的办公环境与社区文化建设
- 雨搭安装合同范本
- 2025至2030年中国自动部分收集器数据监测研究报告
- 2025至2030年中国腿部曲伸机数据监测研究报告
- 2025至2030年中国耐腐型树脂数据监测研究报告
- 景区经营权承包合同(2025)详细条款
- 2025年度物流运输合同解除与货物处理协议
- 二零二五年度反担保抵押担保合同(海洋资源开发)
- 二零二五年度离婚后子女抚养权及监护责任协议
- 新版人教版七年级下册数学全册教案教学设计含教学反思
- 《中国古代寓言》导读(课件)2023-2024学年统编版语文三年级下册
- 《网络攻击与防御》课件第四章 基于系统的攻击与防御
- 供电一把手讲安全课
- JTG∕T F30-2014 公路水泥混凝土路面施工技术细则
- 小学一年级硬笔书法入门.ppt
- 包材食品安全——107种可用于食品包装材料的树脂
- 电子烟烟油配方附计算器
- 《语言学导论》期末复习及练习
- 华师大版七年级下册数学全册教案设计
- 合伙人合同协议书范本
评论
0/150
提交评论