路径规划与轨迹优化 —— A*算法

一、A*算法的思路

前面提到的Dijkstra算法是一种广度优先搜索算法,它以广度作为优先级,这种特性决定了它在搜索到终点前会尽可能大范围的遍历所有节点。我们运行前文的代码,可以看到广度优先搜索的效果有点像“病毒扩散”。

请添加图片描述

但在实际工程应用中,我们希望减少对节点的收录,并使机器人可以尽快的找到搜索方向。我们的思路是加入一个启发式函数来引导路径的规划。

f(n)=g(n)+h(n) f(n) = g(n) + h(n) f(n)=g(n)+h(n)
其中

  • f(n)是节点n的综合优先级。当我们选择下一个要遍历的节点时,我们总会选取综合优先级最高(值最小)的节点。
  • g(n) 是节点n距离起点的代价。
  • h(n) 是节点n距离终点的代价,这也就是A*算法的启发函数。

加入启发式函数,可以形象的理解为终点的位置对规划产生了一个"引力",促使着收录节点时更快的向终点进发。所以起点和终点都在影响着A*算法的行为

  • 当启发函数h(n)始终为0,则将由g(n)决定节点的优先级,此时算法就变成了Dijkstra算法。
  • 如果h(n)始终小于等于节点n到终点的代价,则A*算法保证一定能够找到最短路径。但是当h(n)的值越小,算法将遍历越多的节点,也就导致算法越慢。
  • 如果h(n)完全等于节点n到终点的代价,则A*算法将找到最佳路径,并且速度很快。可惜的是,并非所有场景下都能做到这一点。因为在没有达到终点之前,我们很难确切算出距离终点还有多远。
  • 如果h(n)的值比节点n到终点的代价要大,则A*算法不能保证找到最短路径,不过此时会很快。

所以A*算法能找到最短路径,依然保证最优性的条件是

h(n)≤h(n)真实距离 h(n) \leq h(n)_{真实距离} h(n)h(n)

A*算法在算法流程上只比Dijkstra算法多加入了启发式函数,其余没有变化

在这里插入图片描述

二、 地图距离

补充一些关于地图距离的知识点。不同的地图影响着启发式函数的值。

曼哈顿距离

如果机器人的行走规则中只允许朝上下左右四个方向移动,则使用曼哈顿距离来衡量两个点之间的距离。

def heuristic(node):
    dx = abs(node.x - goal.x)
    dy = abs(node.y - goal.y)
    return D * (dx + dy)  #D是代价

在这里插入图片描述
对角距离

如果机器人可以斜向行走,则使用对角距离。计算对角距离的函数如下

def heuristic(node):
    dx = abs(node.x - goal.x)
    dy = abs(node.y - goal.y)
    return D * (dx + dy) + (D2 - 2 * D) * min(dx, dy)

其中D2是斜向行走的代价,它的计算如下

D2=2D D2 = \sqrt 2 D D2=2 D
在这里插入图片描述
欧式距离

欧几里得距离是指两个节点之间的直线距离。计算函数如下

def heuristic(node):
    dx = abs(node.x - goal.x)
    dy = abs(node.y - goal.y)
    return D * sqrt(dx * dx + dy * dy)

三、代码

定义机器人的运动规则有上下左右和斜向方式

    def get_motion_model():    #相当于赋予权重
        # dx, dy, cost(x轴方向,y轴方向,代价(距离))
        motion = [[1, 0, 1],
                  [0, 1, 1],
                  [-1, 0, 1],
                  [0, -1, 1],
                  [-1, -1, math.sqrt(2)],
                  [-1, 1, math.sqrt(2)],
                  
### A*算法概述 A*(A-Star)算法是一种静态路网中求解最短路径最为有效的直接搜索方法之一,同时也是处理多种搜索问题的重要工具[^1]。该算法不仅适用于网格环境下的路径查找,在其他类型的图结构上同样表现优异。 ### 启发式搜索概念 启发式搜索不同于传统的盲目搜索策略——比如广度优先搜索(BFS)或是深度优先搜索(DFS),这类技术并不依赖于任何特定的信息来进行决策;相反,启发式搜索会利用额外的知识或线索来指引探索的方向,使得寻找解决方案的过程更加高效[^3]。 对于每一个待考察的状态点而言,都会计算一个评分f(n)=g(n)+h(n)[^4]: - **g(n)** 表示从起点到达当前节点n的实际成本; - **h(n)** 是对未来可能发生的事件的一种预测性的衡量标准,即预估从当前位置前往终点所需的成本。 这种机制允许程序能够专注于最有希望成功的路线,而不是无差别地遍历整个空间。 ### Python实现案例 下面给出一段简单的Python代码片段展示如何基于上述原则构建基本版的A*寻径器: ```python import heapq def a_star_search(graph, start, goal): frontier = [] heapq.heappush(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 next_node in graph.neighbors(current): # Assume 'graph' has method neighbors(node) new_cost = cost_so_far[current] + graph.cost(current, next_node) # And also assume it can calculate edge costs if next_node not in cost_so_far or new_cost < cost_so_far[next_node]: cost_so_far[next_node] = new_cost priority = new_cost + heuristic(goal, next_node) # Define your own function to estimate remaining distance. heapq.heappush(frontier, (priority, next_node)) came_from[next_node] = current return reconstruct_path(came_from, start=start, goal=goal) def heuristic(a, b): """Simple Manhattan Distance as an example.""" (x1, y1) = a (x2, y2) = b return abs(x1 - x2) + abs(y1 - y2) def reconstruct_path(came_from, start, goal): path = [goal] while path[-1] != start: path.append(came_from[path[-1]]) path.reverse() return path ``` 这段脚本定义了一个`a_star_search()`函数接受三个参数:表示地图关系的数据结构(`graph`)、出发位置(`start`)以及目的地坐标(`goal`)。内部逻辑遵循了之前提到的原则,并且采用了最小堆数据结构优化选取下一个要访问的位置。 ### 应用场景举例 除了经典的二维平面内的导航任务外,A*还可以应用于诸多领域内涉及最优方案挑选的任务当中,例如但不限于: - 自动驾驶汽车规划行车线路; - 游戏AI角色移动控制; - 物流配送中心货物分拣机器人轨迹安排; - 复杂网络拓扑下通信链路建立等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值