十五数码问题
一、实验目的
二、实验分析
2.1 A*算法
定义一个评价函数 f,对当前待搜索状态进行评估(既考虑从起始节点到节点 n 的花费,又考虑从节点 n 到达目标节点的费用),然后找出一个最有希望的节点来扩展,当满足条件h(n)≤h*(n)为A算法。g(n) 是在状态空间中从初始状态到状态n的实际代价,h(n) 是从状态n到目标状态的最佳路径的估计代价。
A算法的控制策略为:按照 f(n)值递增的顺序对 OPEN 中的元素进行排序,f(n)值小的节点排在前面,大的放在 OPEN 表的后面。A*算法使用OPEN表来存放待扩展的节点,使用CLOSED表来存放已经扩展完的节点。
2.2 实验分析
f(n)=g(n)+h(n),g(n)为根据搜索历史情况,是对已经走过的深度的估计,h(n)为启发函数,是对未来的估计。在此实验中,我们通过设置判断条件规定节点不会重复扩展,例如从状态(1)到状态(2),即节点向上移动又接着向下移动的情况是不被允许的。
三、实验设计
启发函数会影响A算法的行为,因此启发函数的设计至关重要,在此实验中,我们设计了三种启发函数,分别是w_n、p_n和wp_n,w_n为“不在位” 的将牌个数,p_n为每个将牌与其目标位置之间最短距离的总和,wp_n为0.5w_n+0.5*p_n。针对这三种不同的启发函数,从扩展节点数、生成节点数、算法运行时间方面进行了对比分析。
3.1 启发函数
- w(n)
w(n)为“不在位” 的将牌个数,也就是状态n与目标状态不同的元素个数。 - p(n)
p(n)为每个将牌与其目标位置之间最短距离的总和,也就是状态n与目标状态各个元素的曼哈顿距离,定义公式和曼哈顿距离图如下。
- 自定义启发函数wp_n
在此实验中,我们自己定义了一个启发函数,wp_n既考虑了w(n),又考虑了p(n),wp_n定义如下:
3.2 实验设计描述
3.3 实验代码
实验代码见github:https://github.com/taylor233316/class_work/tree/main/AI-homework
四、实验结果与分析
4.1 实验结果
(1)我们利用启发函数进行搜索,程序运行时需选择启发函数类型。
(2)当启发函数为w(n)时,搜索成功状态图和生成节点数、搜索时间(搜索时间每次不完全相同)等结果如下图所示。
(3)当启发函数为p(n)时,搜索成功状态图和生成节点数、搜索时间等结果如下图所示。
(4)当启发函数为自定义函数wp_n时,搜索成功状态图和生成节点数、搜索时间等结果如下图所示。
4.2 对比分析
三种启发函数的扩展节点数、生成节点数、算法运行时间如下表所示,从表中可以看出,我们自定义的启发函数搜索效率要比w(n)和p(n)高,搜索效率有了较大的提升,而w(n)和p(n)函数搜索效率相差并不是太大,在十五数码问题中,w(n)要优于p(n)。
4.3 实验分析
除了本实验给出的这个测试用例,我测试了其他情况,发现许多测试用例难以快速用本实验定义的A算法求出,本实验定义的三种启发函数都难以快速搜索到目标状态,因此后续我将尝试使用线性冲突、IDA算法、Pattern Database这三种方法来提高搜索效率。
五、总结
如果想使用A*进一步优化fifteen star 问题,可以参考一下以下这几篇博客。
使用A*和pattern databases解决十五数码问题
国外小哥的一个编程作业,比较详细