A*算法求解迷宫寻路问题(启发式算法) 您所在的位置:网站首页 算法类问题的求解框图 A*算法求解迷宫寻路问题(启发式算法)

A*算法求解迷宫寻路问题(启发式算法)

2024-07-14 20:04| 来源: 网络整理| 查看: 265

A*算法求解迷宫寻路问题 求点赞关注改进2023-03-24 实验内容设置相关数据设置两种地图设置两种启发式函数 性能分析分析不同起点终点分析不同启发式函数分析不同地图 总结附录代码

A*算法求解迷宫寻路问题资源链接如右:A*算法求解迷宫寻路问题

求点赞关注

如果觉得这篇文章对你有帮助请点赞收藏加关注啊,真的很谢谢大家!大家可以进入我的CSDN主页查看其它文章,都是我在进行课后题目与课程设计时遇到的一些问题,如果你正在学习人工智能,一定会有所收获,并且可以在我的GitHub仓库主页下载相关代码,如无法进入GitHub仓库主页也可以进入Gitee进行查看,后续我也会根据需求不断完善。

lazyn的CSDN_blog_code(GitHub) lazyn的CSDN_blog_code(Gitee)

同时如果想要系统化的学习人工智能,可以进入下面的网站进行学习

通俗易懂,风趣幽默的人工智能学习网站-床长人工智能教程

作为人工智能专业的学生,我认为该网站的课程设置足够专业与完整,由浅入深,基本涵盖了当前人工智能的热门领域并且在不断完善,目录简洁明了,大家可以对照目录进行查漏补缺,作为读者,我发现课程内容通俗易懂,风趣幽默,可以激发大家的学习兴趣。

改进 2023-03-24 删除 op 函数,通过 sorted 函数对 Open 表根据代价从大到小排序,每次取 Open 表最后一个值作为扩展节点每次获得 Open 表时判断节点是否在 Opens 表中,即是否已扩展,避免重复判断新增变量 crossings 用于存储未走的分叉节点,实现寻路回溯

修改后代码可以实现评论区迷宫的寻路,结果如下图所示。 修改后代码结果

感谢评论区 weeknight, m0_57493007, 子夜ザ“, 格”式化 等人的指正。

实验内容

在一个n×m的迷宫里,入口坐标和出口坐标分别为(startx,starty)和(endx,eny),每一个坐标点有两种可能:0或1,其中0表示该位置允许通过,1表示该位置不允许通过。以寻路问题为例实现A*算法的求解程序,设计两种不同的估价函数。

设置相关数据 设置两种地图

根据题意,用矩阵设置两个地图。 地图1:设置5行5列的迷宫,代码如下:

a = np.mat([[0, 0, 0, 0, 0], [1, 0, 1, 0, 1], [0, 0, 1, 1, 1], [0, 1, 0, 0, 0], [0, 0, 0, 1, 0]])

地图2:设置20行20列的迷宫,代码如下

a = np.mat([[0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1], [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1], [0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1], [1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1], [0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1], [0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1], [1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1], [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1], [0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1], [0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1], [0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1], [1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0], [0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0]]) 设置两种启发式函数

定义估价函数 f ( n ) = g ( n ) + h ( n ) f(n)=g(n)+h(n) f(n)=g(n)+h(n) 式中, g ( n ) g(n) g(n)为起点到 n n n状态的最短路径代价的估计值, h ( n ) h(n) h(n)是 n n n状态到目的状态的最短路径代价的估计值。 令 g ( n ) g(n) g(n)为起点到 n n n状态的曼哈顿距离,代码如下:

def gs(i, j): return abs(i - startx) + abs(j - starty)

定义两种启发式函数。 启发式函数 h 1 ( n ) h_1 (n) h1​(n): h 1 ( n ) = 10 × ( ∣ n x − e n d x ∣ + ∣ n y − e n d y ∣ ) h_1 (n)=10×(|n_x-endx|+|n_y-endy|) h1​(n)=10×(∣nx​−endx∣+∣ny​−endy∣),代码如下:

def h1(i, j): return 10*(abs(i - endx) + abs(j - endy))

启发式函数 h 2 ( n ) h_2 (n) h2​(n): h 2 ( n ) = ( n x − e n d x ) 2 + ( n y − e n d y ) 2 h_2 (n)=(n_x-endx)^2+(n_y-endy)^2 h2​(n)=(nx​−endx)2+(ny​−endy)2,代码如下:

def h2(i, j): return pow(i - endx, 2) + pow(j - endy, 2) 性能分析 分析不同起点终点

采用地图2,具体如下图1,启发式函数 h 1 h_1 h1​进行分析,分别设置起点为(1,1)和(9,5),终点为(20,20)、(18,20)。 图1 地图

(1,1)→(20,20)的路径如图2,(9,5)→(18,20)的路径如图3。 图2 路径1 图3 路径2 两次寻路过程的性能分析如下表1。

路径(1,1)→(20,20)(9,5)→(18,20)扩展节点数10073生成节点数7157运行时间0.001997950.00200462

由上述图表可知路径延长后运行时间会相对变长,扩展节点及生成节点也会相应增多,且两次寻找的路程有重合的部分,所以寻找到的路径为较优路径。

分析不同启发式函数

采用地图2,启发式函数 h 1 h_1 h1​, h 2 h_2 h2​进行分析,设置起点为(1,1),终点为(20,20),两次寻路过程的路径,扩展节点数、生成节点数和运行时间分别如下图4,图5。 图4 启发式函数h1 图5 启发式函数h2

由图表可知,两种启发式函数所用时间相近,但 h 2 h_2 h2​相比 h 1 h_1 h1​所扩展的节点数会减少,仔细分析可以发现启发式函数 h 1 h_1 h1​在路径108位置首先寻找了另一条岔路,从而相比启发式函数 h 2 h_2 h2​多扩展了3个节点。

分析不同地图

上述过程一直采用地图2进行实验,为验证程序的普适性,现采用地图1进行实验。经过分析,选择上述较优的启发式函数 h 2 h_2 h2​进行分析。寻路问题初始节点为(1,1),目标节点为(5,5),寻路路径如图6。 图6 地图1

汇总上述性能报告如下表2。

地图启发式函数扩展节点数生成节点数运行时间地图1 h 2 h_2 h2​14130.00100136地图2 h 1 h_1 h1​100710.00199795地图2 h 2 h_2 h2​97710.00251245 总结

A*算法在地图寻路问题中具有很好的优势,相比宽度优先搜索,效率更高,所耗时间更少,相比深度优先搜索,可以解决其不能找到最优解的不足,具有较高的应用价值。该算法的重点及难点就是启发式函数的选择,通过上述实验,可以发现启发式函数 h 2 h_2 h2​相比 h 1 h_1 h1​效果更好,但仍存在一些问题,需要继续找寻更优的启发式函数。

附录代码

主程序代码如下,其中用到的方法和地图在上述代码中已定义,故不再给出。设置不同的起点与终点需相应的更改startx, starty和endx, endy的值。

print("地图为:(1表示墙,0表示路)") for l in range(len(a)): for m in range(a[0].size): print(a[l, m], end=' ') print('') print('') startx, starty = 1, 1 endx, endy = 5, 5 if a[startx - 1, starty - 1] == 1: print("起点%s位置为墙,最短路径寻找失败!" % ([startx, starty])) else: # 存储已扩展结点,即所有寻找的节点 Close = [[startx, starty]] # 存储已生成节点,即最终走过的节点 Opens = [[startx, starty]] # 存储未走的分叉节点 crossings = [] # 设置在原地图行走的路径值 road = 100 start = time.time() rows, cols = a.shape while True: # 判断最后走过的节点是否为终点 if Close[-1] != [endx, endy]: Open = [] # 减1得到数组下标值 i, j = Close[-1][0] - 1, Close[-1][1] - 1 # 对当前节点上下左右四个节点进行判断 for ni, nj in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]: if [ni + 1, nj + 1] not in Opens and 0


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有