人工智能实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一:用A*算法解决旅行商问题
一、问题描述
货郎担(旅行商)问题:
设有n个城市,城市之间均有道路,一个旅行商从某城市出发,经过其余n-1个城市一次且仅一次,最后回到出发的城市,他如何走才能使他所走的路程最短?
二、A*算法描述
A*算法是N.Nillson于1971年提出的一种有序搜索算法,该算法被认为是求解人工智能问题的最成功的技术理论之一。Nillson指出对于某一已到达的现行状态,如已到达图中的n节点,它是否可能成为最佳路径上的一点的估价,应由估价函数f(n)值来决定。f(n) = g(n)+h(n),其中g(n)是从初始节点到节点n已经付出的代价,h(n)是启发函数。A*算法限制其估价函数中的启发函数h(n)满足:对所有节点n均有h(n)≤h*(n),其中h*(n)是从节点n到目标节点的最小代价,即最佳路径上的实际代价(若有多个目标节点则为其中最小的一个)。
A*算法的具体步骤如下:
(1) 建立一个只含有起始节点S的搜索图G,图中每个节点有一个指向其父节点的指针,S的这一指针为一特殊值(如0),并把S放入未扩展节点表OPEN中,计算f(S);
(2) 建立已被扩展的节点表CLOSED,初始时表为空;
(3) LOOP:若OPEN表为空,则失败退出;
(4) 把OPEN表中的第一个节点移出并放入CLOSED表中,称此节点为n节点;
(5) 若n为目标节点,则成功退出;
(6) 扩展节点n,对其每个后继子节点m:
(a) 计算f(m);
(b) 若m不在G中,将其作为n的后继节点加入G,设置一个通向n的指针,并把它加入OPEN表;
(c) 若m已在G中,则比较刚计算的f值与原先的f值,如新值较小,则以新值代替旧值,并调整有关指针;此时,若m在CLOSED表中,则把它移回
OPEN表;
(7) 按f值由小到大重排OPEN表;
(8) 转LOOP。
三、旅行商问题算法描述
节点(A...XY)的代价=起始城市到X城的代价+X城到Y城的代价,其中的代价可以是距离,费用或者时间等。
节点(A…XY)的启发值=(城市总数-已访问的城市数-1)*min{所有两城之间的代价}。
在程序中的实现:
p->gvalue=p_min->gvalue+map[p_min->num-1][i];
p->hvalue=min*(number-p->level-1);
p->fvalue=p->gvalue+p->hvalue;
其中gvalue:g(n) hvalue:h(n) fvalue:f(n)
p_min->gvalue:起始城市到X城的代价
map[p_min->num-1][i]:一个二维数组,X城到Y城的代价
min:所有两城之间的代价的最小值
number:城市总数
p->level:城市节点所处于搜索树的层次,和已访问的城市数同值
在本程序中定义一个结构体node用于表示城市节点:
struct node
{
int num;
int fvalue;//f值
int gvalue;//g值
int hvalue;//h值
int level; // 城市节点所处于搜索树的层次数,和已访问的城市数同值
struct node *parent;//父节点
struct node *next;//后继
struct node *front;//前驱
};
struct final_path
{
struct node *head;
struct node *tail;
}Open;
定义一个结构体final_path表示Open表,Open表用于存放扩展出来的节点
测试数据的输入使用矩阵表示完全图,使用二维数组map[100][100]存放。
四、程序流程
(1)将path数组中元素值置下标值:path[i]=i+1
(2)按要求输入城市距离矩阵。
(3)默认从第一个点开始搜索,并将path[0]=-1,表示该点已被纳入路径.
(4)扩展刚刚被纳入路径的节点,扩展的方法为在path数组中搜索值不为-1的元素,为之创建节点写入数据(包括g值,h值,f值,parent节点)并纳入Open表中。
(5)在Open表中搜索f值最小的节点确定为当前的最优路径点p_min,并且将上一次的最优路径点所在的路径上所有节点的path表中的元素值改为其下标值,表示删除原路径,同时将p_min所在的路径上所有节点的path表中元素值改为-1,表示创建新路径。
(6)回第4步循环,直至path表中所有的元素值均为-1退出循环。
(7)由此获得最后一次的最优路径点,利用结构体中的parent指针得到最佳路径,输出最佳路径。
(8)程序退出。
五、测试用例
六、程序运行结果
程序的运行环境是Windows XP,Microsoft Visual C++ 6.0
七、心得体会
通过本实验我进一步掌握了A*算法,弄清了A算法和A*算法的区别与联系,掌握了启发式搜索算法的原理。A*算法的关键就是启发式函数的设计,必须满足h(n)≤h*(n)。此外通过本次试验进一步锻炼了我的编程能力和阅读程序的能力。