Python实现A*算法的十五数码

本文针对15数码游戏中的A*搜索算法进行优化,通过调整节点计数位置和改进启发式函数,显著减少了搜索节点数量和计算时间,提高了算法效率。

参考以下博客实现15数码

https://blog.youkuaiyun.com/qq_35976351/article/details/82767029

发现其时间和节点复杂度为:

未修改的时间复杂度和节点数​​​

 然后发现其代码中计算节点数量是不合理的

计数不合理

 如上图第12行所示:它是在判重前对节点计数。因为如果重复了,我们并没有把该状态再次加到哈希表和堆中,所以不应该再次计算一次。应该把第SUM_NODE_NUM+=1放在hash_set.add(h)后面或者前面。修改后结果为:

修改计数位置之后

 发现数量确实少了不少。继续阅读发现其hn并没有真正的发挥启发式函数的作用:

第8行有问题

 此时的hn是按照其父节点状态和目标节点状态所计算的,这就意味着其所产生的所有子节点fn都和其父节点相同。所以产生的所有子节点的fn都是相等的(因为gn都是父节点加1和hn都是父节点状态与目标节点状态的距离)。所以要让hn是其当前节点状态与目标节点状态的距离,即state和end_node.state的距离,故修改manhattan_dis()函数为:

把cur_state=cur_node.state和end_state=end_node.state那两行注释掉 ,函数传入参数改为cur_state和end_state

在调用该函数(即上上图的第八行代码)的时候参数传递改为以下

 hn = dis_fn(state, end_node.state)  # 启发的距离函数

然后其结果为:

这样我们就发现不仅节点大大的减少,而且时间也少了0.1s左右。所以修改完成。

总结:此博客是在上述博客源码的基础上修改的,可复制其代码,然后按照这个步骤修改就行。这一次真正体会到代码的位置和启发式函数到底有多大的差别,代码路还很长,不忘初心,继续前行。

附测试用例:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值