Hybrid Astar 算法剖析和实现(一)

在学习资料满天飞的大环境下,知识变得非常零散,体系化的知识并不多,这就导致很多人每天都努力学习到感动自己,最终却收效甚微,甚至放弃学习。我的使命就是过滤掉大量的无效信息,将知识体系化,以短平快的方式直达问题本质,把大家从大海捞针的痛苦中解脱出来。

0 前言

网络上讲Astar算法的很多,但讲Hybrid Astar算法的相对来说很少,而且基本上都停留在理论层面,很少结合代码来讲。本篇/系列文章旨在帮助新接触该算法的同学能够从理论到代码彻底吃透该算法,并应用到自己的项目中去。

1 什么是Hybrid Astar算法

Hybrid Astar是Astar算法的扩展。或者可以理解为Astar算法在自动驾驶领域应用的定制版。因为整体的搜索框架(思想)大体是一致的,只不过对每个模块的内部实现做了调整。比如,Astar算法子节点扩张的方向比较固定(4方向或8方向),Hybrid Astar则改造成符合车辆运动学的扩张方式。再比如,Astar算法的启发函数直接使用曼哈顿距离,而Hybrid Astar则使用符合车辆运动学的R-S曲线和无碰撞路径的最大值来作为启发函数。

简单理解就是,Hybrid Astar是适合车辆进行搜索的Astar算法的高端定制版。

Tips:没有接触过Astar算法的可以先看一下这个链接Introduction to the A* Algorithm (redblobgames.com)。等做完Hybrid Astar系列,回头再把Dijkstra算法和Astar算法的剖析补上。

2 Hybrid Astar算法有什么用

该算法主要被应用在自动驾驶领域的下面几个场景:

  • APA(辅助泊车)
  • AVP(代客泊车)
  • U-Turn(行车场景下的车辆掉头)

3 算法的核心思想

个人认为Hybrid Astar算法的核心思想和Astar是一样的:

  • 使用局部最优逼近全局最优。
  • 连续问题离散化,以便可以迭代计算。

其实大部分的优化算法都是这样一个思路。当然Hybrid Astar会有自己的一些特点,每个特点的背后肯定也蕴含着精妙的设计思想,我们后面会逐个剖析。

4 算法的重要组成部分

Hybrid Astar算法主要包括下面几个要素:

  • 状态节点
  • 状态空间栅格
  • 迭代搜索
  • 节点拓展
  • 碰撞检测
  • 代价计算-g
  • 代价计算-h

Astar算法也包含上述几个要素(七龙珠),但Hybrid Astar将每个要素都进行了升级或者说是定制。

5 总结

本篇主要介绍了一下Hybrid Astar算法的概貌,和重要组成部分,后文我们会将这几个要素一一攻克。

恭喜你又坚持看完了一篇博客,又进步了一点点!如果感觉还不错就点个赞再走吧,你的点赞和关注将是我持续输出的哒哒哒动力~~

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
AStar算法是一种常用的路径规划算法,其主要思路是在图或网格中找到一条最短路径。 具体实现思路如下: 1. 初始化起点和终点,并将起点加入open列表中。 2. 从open列表中选取f值最小的节点作为当前节点,并将其加入close列表中。 3. 根据当前节点,找到其相邻的节点,并计算它们的f值(f = g + h),其中g表示从起点到当前节点的距离,h表示从当前节点到终点的估算距离。 4. 对于每个相邻节点,如果它已经在close列表中,或者障碍物阻挡了它,或者它已经在open列表中但是新的路径比原路径更长,则忽略它。 5. 否则,将当前节点作为该相邻节点的父节点,更新该相邻节点的g值和f值,并将其加入open列表中。 6. 重复执行步骤2-5,直到终点被加入close列表中或者open列表为空。 7. 如果终点被加入close列表中,则说明找到了一条最短路径,根据每个节点的父节点可以回溯得到该路径。 以下是Python的示例代码: ```python import heapq def astar(start, end, obstacles, grid_size): """ A*算法实现 :param start: 起点坐标 (x, y) :param end: 终点坐标 (x, y) :param obstacles: 障碍物坐标列表 [(x1, y1), (x2, y2), ...] :param grid_size: 网格大小 (width, height) :return: 最短路径坐标列表 [(x1, y1), (x2, y2), ...] """ # 计算启发式距离 def heuristic(a, b): return abs(b[0] - a[0]) + abs(b[1] - a[1]) # 判断坐标是否在网格内 def in_grid(x, y): return 0 <= x < grid_size[0] and 0 <= y < grid_size[1] # 判断坐标是否为障碍物 def is_obstacle(x, y): return (x, y) in obstacles # 获取周围相邻的坐标 def get_neighbors(x, y): neighbors = [(x+1, y), (x, y+1), (x-1, y), (x, y-1)] return filter(lambda p: in_grid(*p) and not is_obstacle(*p), neighbors) # 初始化起点和终点 start_node = (0, start, None) end_node = (heuristic(start, end), end, None) # 初始化open列表和close列表 open_list = [start_node] close_list = set() # 循环直到找到终点或open列表为空 while open_list: # 选取f值最小的节点作为当前节点 current_node = heapq.heappop(open_list) if current_node[1] == end: # 找到终点,回溯得到路径 path = [] while current_node: path.append(current_node[1]) current_node = current_node[2] return path[::-1] # 将当前节点加入close列表中 close_list.add(current_node[1]) # 处理相邻节点 for neighbor in get_neighbors(*current_node[1]): # 如果相邻节点已经在close列表中,忽略它 if neighbor in close_list: continue # 计算相邻节点的f值 g = current_node[0] + 1 h = heuristic(neighbor, end) f = g + h # 如果相邻节点已经在open列表中,更新它的f值和父节点 for node in open_list: if node[1] == neighbor: if f < node[0]: open_list.remove(node) node = (f, neighbor, current_node) heapq.heappush(open_list, node) break else: # 否则,将相邻节点加入open列表中 node = (f, neighbor, current_node) heapq.heappush(open_list, node) # open列表为空,无法找到路径 return [] ``` 通过调用`astar`函数,传入起点、终点、障碍物和网格大小,即可得到最短路径坐标列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

穿越临界点

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

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

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

打赏作者

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

抵扣说明:

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

余额充值