A*算法的介绍

提示:文章写完后,目录可以自## 标题动生成,如何生成可参考右边的帮助文档


一、A*算法的由来及应用背景

在这里插入图片描述

二、A*算法的基本原理

1.基本数学原理

A*算法作为启发式搜索算法,其更新估值F来进行搜索
F = G + H F=G+H F=G+H
F F F: 当前节点的总代价
G G G: 开始节点到当前节点的移动距离(实际代价)
H H H: 从当前节点到终点的估计移动距离(估计代价)

计算G代价为从起点到当前节点经过的所有边的距离之和。
计算H代价的启发函数h包括曼哈顿距离、对角距离(切比雪夫距离)、欧几里德距离。

注意点
1.计算H时,要忽略路径中的障碍物。这是对剩余距离的估算值,而不是实际值,因此H代价为估计代价。

2.在进行全局地图路径规划时,将环境信息转化为一个网格地图,其中每个网格表示环境的一个区域,障碍物的区域可以标记为障碍物网格,因此障碍物节点是已知的。

3.已知A*算法保证能够找到最短路径的条件是满足以下两个条件:
(1)启发函数h(n)必须满足单调性(即估计的代价不会超过从节点n到目标节点的实际代价),
(2)地图必须是可行的,即不存在无法通过的障碍物或无法到达的区域。

2.启发函数的选择

2.1曼哈顿距离

曼哈顿距离: D = ∣ x 2 − x 1 ∣ + ∣ y 2 − y 1 ∣ D=|x_{2}-x_{1}|+|y_{2}-y_{1}| D=x2x1+y2y1,如下图:
粗=曼哈顿距离
如果图形中只允许朝上下左右四个方向移动,则可以使用曼哈顿距离。计算从当前栅格横向或纵向移动到达目标所经过的方格数。
在这里插入图片描述
例如在上图中中心节点可以朝着上下左右拓展,这时采用曼哈顿距离作为启发函数更有效。当拓展节点存在障碍物时:
在这里插入图片描述
A*算法会根据地图中的网格来判断每个节点的状态,即是否为障碍物节点。当算法扩展节点时,如果该节点是障碍物节点,则不会将其加入到待扩展节点集合中,从而避免沿着该节点继续搜索,这样就能够有效地避免穿越障碍物。

2.2对角距离(切比雪夫距离)

对角距离(切比雪夫距离): D = m a x ( ∣ x 2 − x 1 ∣ + ∣ y 2 − y 1 ∣ ) D=max(|x_{2}-x_{1}|+|y_{2}-y_{1}|) D=max(x2x1+y2y1),如下图:
对角距离
如果图形中允许朝八个方向移动,则可以使用对角距离。对角距离更适合处理允许斜向移动的情况,因为它考虑了斜向移动时的额外距离,使得估算更加准确。
在这里插入图片描述
当拓展节点存在障碍物时:
在这里插入图片描述

2.3欧几里德距离

欧几里德距离: D = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 D=\sqrt{(x_{2}-x_{1})^2+(y_{2}-y_{1})^2} D=(x2x1)2+(y2y1)2 ,如下图:
欧几里得距离
允许朝任何方向移动则可以使用欧几里德距离。欧几里德距离直接计算两点之间的距离,更符合实际情况.。

注意:
启发函数跟拓展方式没有一定的捆绑关系,上述只是建议在哪种拓展节点的方式用何种启发函数。选择哪种启发函数取决于应用场景的具体情况,可以根据实际情况进行选择或者结合多种启发函数进行综合考虑。上述部分内容由ChatGPT-plus4.0给出,如有错误请大家自行判断。

三、A*算法的程序实现

1.算法逻辑

1.初始化开始节点S,最终节点G,初始化列表open,closed,初始化全局地图(网格地图)
2.从开始节点S出发,把S作为一个待检查的方格,放入open列表
3.寻找开始节点S周围可以到达的方格(最多八个),将它们放入open列表,并设置它们的父节点为S
4.从“open列表”中删除开始节点S,并将S放入到closed列表中
5.计算每个周围方格的F值 F=G+H
6.从open列表中选择F值最小的方格a,将其从open列表放入到closed列表中
7.检查a所有邻近的方格
1)障碍物和close列表中的方格不考虑
2)如果这些方格不在open列表中,将它们加入open列表,计算这些方格的F值,并设置父节点为a
3)如果某相邻的方格c已经在open列表中,计算新的路径从S到达方格c(即经过a的路径), 判断是否需要更新父节点和F值:如果新节点c的G值更低,则修改父方格为方格a,重新计算F值,H值不需要改变(因为方格到达目标点的预估代价是固定的),如果新节点c的G值比较高,则说明新的路径代价更高,则值不做改变(G值不变也不更新)
8.继续从open列表中找出F值最小的,从open列表中删除,添加到close列表,再继续找出周围可以到达的方块,如此循环
9.结束判断:当open列表中出现目标方块G时,说明路径已找到;当open列表中没有了数据,说明没有合适路径。

2.实验结果

20 ∗ 20 20*20 2020的栅格地图中,障碍物自定产生,启发函数h分别采用曼哈顿距离和欧几里德距离,每个节点可以朝四个方向扩展。得到的路径规划如左图。其中阴影部分为加入过列表(或搜索过)的方格。

在这里插入图片描述当我们增大网格地图,此时利用A进行路径规划又会得到怎么的结果呢
在这里插入图片描述 200 ∗ 200 200*200 200200的栅格地图中,障碍物随机产生,障碍物覆盖率占地图的20%,启发函数h分别采用曼哈顿距离和欧几里德距离,得到的路径规划如左图。
A
算法的启发式搜索过程中启发函数的估计值越接近真实值,规划效率越高。
在网格地图中,每个节点可以朝八个方向扩展,此时曼哈顿距离更能准确地反映两个节点之间的距离。相比之下,欧几里德距离计算的H值偏小,同时其需要进行开方运算,耗时较长。

在这里插入图片描述有小伙伴需要程序的可以私我。


四、A*算法的总结

A*算法的优缺点

优点:
1.最优性:在满足一定条件下, A算法能够保证找到最短路径。
2.快速性:相对于其他搜索算法, A
算法的搜索速度较快,因为它能够通过启发式函数来减少搜索的路径数。这使得A算法在处理大规模的搜索问题时非常高效。
3.适用性广泛: A
算法可以用于解决各种路径搜索问题,例如在计算机游戏中寻找最佳路径、在机器人导航中寻找最短路径等等。

缺点:
1.启发式函数不易设计: A算法需要使用启发式函数来估算每个节点到目标节点的距离,但是启发式函数2.的设计并不是一件容易的事情。如果启发式函数设计不好,那么搜索效率将会受到很大的影响。
存储空间占用较大: A
算法需要存储搜索过程中的节点信息,因此当搜索的状态空间较大时,它需要占用较大的存储空间。
3.可能陷入局部最优解:虽然A算法能够保证找到最短路径,但是当启发式函数不够好时, A算法可能会陷入局部最优解,而无法找到全局最优解。

  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
A*算法是一种启发式搜索算法,用于在图形或树形搜索空间中寻找最短路径。它是一种基于贪心算法的搜索算法,它通过评估每个节点的启发式估计来决定下一个节点的选择。A*算法的优势在于它可以利用启发式信息,从而更快地找到最短路径。 A*算法的主要思想是维护两个集合:开放集和关闭集。开放集用于存储待扩展的节点,而关闭集用于存储已经扩展过的节点。在每个扩展步骤中,A*算法选择开放集中启发式估计最低的节点进行扩展,并将其从开放集中移除,并加入关闭集。然后,算法将扩展节点的邻居加入开放集中,并计算它们的启发式估计值。 A*算法的启发式估计函数可以是单调的,即对于任意两个相邻节点,从一个节点到另一个节点的实际代价不会小于从一个节点到另一个节点的启发式估计值。这种单调性保证了A*算法能够找到最短路径。 以下是A*算法的基本步骤: 1. 将起点加入开放集中,并将其启发式估计值设置为0。 2. 从开放集中选择启发式估计最低的节点进行扩展,并将其从开放集中移除加入关闭集中。 3. 对于扩展节点的每个邻居,如果邻居不在关闭集中,则将其加入开放集中,并计算邻居的启发式估计值。 4. 如果目标节点已加入关闭集中,则算法结束,否则返回第2步。 A*算法有许多应用,如游戏AI中的路径搜索,机器人路径规划,地图路线规划等。 以下是A*算法的Python实现示例: ```python import heapq def a_star_search(start, goal, graph): frontier = [(0, start)] came_from = {} cost_so_far = {} came_from[start] = None cost_so_far[start] = 0 while frontier: _, current = heapq.heappop(frontier) if current == goal: break for neighbor in graph[current]: new_cost = cost_so_far[current] + graph[current][neighbor] if neighbor not in cost_so_far or new_cost < cost_so_far[neighbor]: cost_so_far[neighbor] = new_cost priority = new_cost + heuristic(goal, neighbor) heapq.heappush(frontier, (priority, neighbor)) came_from[neighbor] = current return came_from, cost_so_far def heuristic(a, b): return abs(a[0] - b[0]) + abs(a[1] - b[1]) # Example usage: graph = {'A': {'B': 1, 'C': 4}, 'B': {'D': 3}, 'C': {'D': 2}, 'D': {}} start = 'A' goal = 'D' came_from, cost_so_far = a_star_search(start, goal, graph) print(came_from) # {'A': None, 'B': 'A', 'C': 'A', 'D': 'B'} print(cost_so_far) # {'A': 0, 'B': 1, 'C': 4, 'D': 4} ``` 在这个例子中,我们使用A*算法在一个有向图中搜索从起点到终点的最短路径。在这个例子中,我们使用曼哈顿距离作为启发式估计函数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值