人工智能大作业
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《人工智能》
实验大作业
实验题目:启发式搜索
专业信息与计算科学
年级091001
姓名贾凡
学号091001103
指导老师时华
日期2012年12月11日
一、实验目的:
熟悉和掌握启发式搜索的定义、估价函数和算法过程,并利用A算法求解九宫问题,理解求解流程和搜索顺序。
二、实验方法:
1.先熟悉启发式搜索算法;
2.用C、C++或JA V A 语言编程实现实验内容。
三、实验背景知识:
1.估价函数
在对问题的状态空间进行搜索时,为提高搜索效率需要和被解问题的解有关的大量控制性知识作为搜索的辅助性策略。这些控制信息反映在估价函数中。
估价函数的任务就是估计待搜索节点的重要程度,给这些节点排定次序。估价函数可以是任意一种函数,如有的定义它是节点x处于最佳路径的概率上,或是x节点和目标节点之间的距离等等。在此,我们把估价函数f(n)定义为从初始节点经过n节点到达目标节点的最小代价路径的代价估计值,它的一般形式是:
f(n) = g(n) + h(n)
其中g(n)是从初始节点到节点n的实际代价,g(n)可以根据生成的搜索树实际计算出来;h(n)是从n到目标节点的最佳路径的代价估计,h(n)主要体现了搜索的启发信息。
2. 启发式搜索过程的特性
(1)可采纳性
当一个搜索算法在最短路径存在的时候能保证能找到它,我们就称该算法是可采纳的。所有A*算法都是可采纳的。
(2)单调性
一个启发函数h是单调的,如果
a)对所有的状态n i和n j,其中n j是n i的子孙,h(n i )- h(n j )≤cost(n i,n j ),其中cost(n i,n j )是从n i到n j 实际代价。
b)目标状态的启发函数值为0,即h(Goal)=0.
具有单调性的启发式搜索算法在对状态进行扩展时能保证所有被扩展的状态的f值是单调递增(不减)。
(3)信息性
比较两个启发策略h1和h2,如果对搜索空间中的任何一个状态n都有h1(n) ≤h2(n),就说h2比h1具有更多的信息性。
一般而言,若搜索策略h2比h1有更多的信息性,则h2比h1考察的状态要少。但必须注意的是更多信息性需要更多的计算时间,从而有可能抵消减少搜索空间所带来的益处。3.常用的启发式搜索算法
(1)局部择优搜索算法(瞎子爬山法)
瞎子爬山法是最简单的启发式算法之一。该算法在搜索过程中扩展当前节点并估价它的子节点。最优的子节点别选择并进一步扩展;该子节点的兄弟节点和父节点都不再被保留。当搜索到达一种状态,该状态比它的所有子状态都要好,则搜索停止。因此,该算法的估价函数可表示为f(n) = h(n)。
在一个限定的环境下,瞎子爬山法可能会极大的提高搜索的效率,但是对整个搜索空间而言,可能得不到全局最优解。
(2)最好优先搜索法(有序搜索法)
该算法的估价函数采用f(n) = g(n) + h(n),在搜索过程中算法使用OPEN 表和CLOSE 表来记录节点信息:OPEN 表中保留所有已生成而未考察的节点;CLOSE 表中保留所有已访问过的节点。算法在每一次搜索过程中都会对OPEN 表中的节点按照每个节点的f 值进行排序,选择f 值最小节点进行扩展。算法的描述如下:
① 把起始节点S 放到OPEN 表中,计算f(S),并把其值与节点S 联系起来。
② 若OPEN 是个空表,则算法失败退出,无解。
③ 从OPEN 表中选择一个f 值最小的节点i 。结果有几个节点合格,当其中有一个为目标节点时,则选择此目标节点,否则就选择其中任一个节点作为节点i 。
④ 把节点i 从OPEN 表中移出,并把它放入到CLOSED 的扩展节点表中。
⑤ 若节点i 是个目标节点,则成功退出,求得一个解。
⑥ 扩展i ,生成其全部后继节点。对i 的每个后继节点j :
(a ) 计算f(j)。
(b ) 如果j 既不在OPEN 表中,也不在CLOSED 表中,则用估价函数f 将其添加到
OPEN 表。从j 加一指向其父辈节点i 的指针,以便一旦找到目标节点时记
住一个解答路径。
(c ) 如果j 已则OPEN 表中或CLOSED 表中,则比较刚刚对j 计算过的f 值和前面计
算过的该节点在表中的f 的值。若新的f 值较小,则
(i ) 以此值取代旧值。
(ii ) 从j 指向i ,而不是指向它的父辈节点。
(iii ) 若节点j 在CLOSED 表中,则把它移回OPEN 表。
⑦ 转向②。
四、实验内容:
问题描述:用启发式搜索方法求解下列九宫问题
五、实验原理
启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无谓的搜索路径,提高了效率。在启发式搜索中,对位置的估价是十分重要的。采用了不同的估价可以有不同的效果。我们先看看估价是如何表示的。
启发中的估价是用估价函数表示的,如:最佳优先搜索的最广为人知的形式称为A*搜
索(发音为“A星搜索”).它把到达节点的耗散g(n)和从该节点到目标节点的消耗h(n)结合起来对节点进行评价:f(n)=g(n)+h(n)因为以g(n)给出了从起始节点到节点n的路径耗散,而h(n)是从节点n到目标节点的最低耗散路径的估计耗散值,因此f(n)=经过节点n的最低耗散解的估计耗散.这样,如果我们想要找到最低耗散解,首先尝试找到g(n)+h(n)值最小的节点是合理的。可以发现这个策略不只是合理的:倘若启发函数h(n)满足一定的条件,A*搜索既是完备的也是最优的。
如果把A*搜索用于Tree-Search,它的最优性是能够直接分折的。在这种情况下,如果h(n)是一个可采纳启发式--也就是说,倘若h(n)从不会过高估计到达目标的耗散--A*算法是最优的。可采纳启发式天生是最优的,因为他们认为求解问题的耗散是低于实际耗散的。因为g(n)是到达节点n的确切耗散,我们得到一个直接的结论:f(n)永远不会高估经过节点n的解的实际耗散。
启发算法有:蚁群算法,遗传算法、模拟退火算法等,蚁群算法是一种来自大自然的随机搜索寻优方法,是生物界的群体启发式行为,现己陆续应用到组合优化、人工智能、通讯等多个领域。蚁群算法的正反馈性和协同性使其可用于分布式系统,隐含的并行性更使之具有极强的发展潜力。从数值仿真结果来看,它比目前风行一时的遗传算法、模拟退火算法等有更好的适应性。
六、代码
#include
#include
struct node{
int a[3][3];//用二维数组存放8数码
int hx;//函数h(x)的值,表示与目标状态的差距
struct node *parent;//指向父结点的指针
struct node *next;//指向链表中下一个结点的指针
};
int hx(int s[3][3]){
int i,j;
int hx=0;
int sg[3][3]={1,2,3,8,0,4,7,6,5};
for(i=0;i<3;i++)
for(j=0;j<3;j++)
if(s[i][j]!=sg[i][j])
hx++;
return hx;
}
struct node *extend(node *ex){
int i,j,m,n; //循环变量
int t; //临时替换变量
int flag=0;
int x[3][3];//临时存放二维数组
struct node *p,*q,*head;
head=(node *)malloc(sizeof(node));//head
p=head;