用A*算法解决十五数码问题(人工智能作业)

十五数码问题

一、实验目的

在这里插入图片描述

二、实验分析

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 启发函数

  1. w(n)
    w(n)为“不在位” 的将牌个数,也就是状态n与目标状态不同的元素个数。
  2. p(n)
    p(n)为每个将牌与其目标位置之间最短距离的总和,也就是状态n与目标状态各个元素的曼哈顿距离,定义公式和曼哈顿距离图如下。
    在这里插入图片描述
  3. 自定义启发函数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解决十五数码问题
国外小哥的一个编程作业,比较详细

  • 10
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
A*算法是一种启发式搜索算法,可以用来解决十五数码问题十五数码问题是一种经典的滑块拼图游戏,其中有一个4x4的网格,上面有编号为1到15的方块,还有一个空方块。目标是通过交换方块,将它们按照从1到15的顺序排列好,最后是一个完全有序的网格。 A*算法的基本思想是将问题抽象为一个图,其中每个节点代表一个局面状态,边表示状态之间的转移。我们使用一个启发函数来评估每个节点的优先级,这个函数考虑到从当前状态到目标状态的距离估计。在十五数码问题中,可以使用曼哈顿距离来评估启发函数,即从当前状态到目标状态所需要的最小水平和垂直移动次数之和。 具体实现A*算法解决十五数码问题的步骤如下: 1. 创建一个优先队列,用于存储待扩展的节点。 2. 将初始状态加入优先队列。 3. 从优先队列中选择优先级最高的节点进行扩展。 4. 生成所有可达的下一状态,并计算每个状态的优先级。 5. 将未扩展的状态加入优先队列。 6. 重复步骤3和4,直到找到目标状态。 在Python中实现A*算法解决十五数码问题可以借助以下数据结构和算法: 1. 使用优先队列来存储待扩展的节点,可以使用heapq库实现。 2. 设计一个状态类来表示每个局面状态,包括当前状态、父节点、移动代价、优先级等信息。 3. 利用哈希表来记录已经生成的状态,以避免重复扩展。 4. 实现曼哈顿距离的计算函数来评估每个状态的优先级。 总结来说,借助A*算法的思想和Python的数据结构和算法库,可以较为高效地解决十五数码问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程小白呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值