第四节:对角线距离——八方向移动下的精确距离计算,如何避免高估代价
聊完曼哈顿距离和欧氏距离,咱们来看看实际项目中最常用的一个——对角线距离。
说白了,它就是专门为八方向移动设计的。你想想看,在栅格地图上,机器人既能上下左右走,也能斜着走。这时候再用曼哈顿距离,代价就估高了。为什么?因为斜着走一步,实际距离只有√2,但曼哈顿距离算出来是2。这一来一回,差距就出来了。
4.1 对角线距离的数学定义
先看公式。假设起点是 (x1, y1),终点是 (x2, y2):
dx = |x1 - x2|
dy = |y1 - y2|
对角线距离 = min(dx, dy) * √2 + |dx - dy|
这个公式怎么理解?
我习惯这么想:先尽可能走斜线,走到不能再斜了,剩下的直线部分就直着走。
- min(dx, dy):能走斜线的步数
- √2:斜线一步的实际代价
- |dx - dy|:剩下的直线步数,代价为1
举个例子。起点 (0,0),终点 (5,3)。
dx=5,dy=3。
min=3,所以先走3步斜线,代价 3*1.414 ≈ 4.242。
剩下 |5-3|=2 步直线,代价 2*1 = 2。
总代价 ≈ 6.242。
这个值比曼哈顿距离(5+3=8)小,比欧氏距离(√34≈5.83)大。很合理,对吧?
4.2 为什么曼哈顿距离会高估代价
我在项目中遇到过好几次这样的问题。一开始用曼哈顿距离做A*,结果发现机器人明明可以斜着走,但路径规划出来的路线却绕来绕去。
原因很简单:曼哈顿距离高估了实际代价。
你想想看,从 (0,0) 到 (3,3),曼哈顿距离是6。但实际走对角线,只需要3步,代价约4.242。差了将近2个点。
高估代价会带来什么后果?
- A* 算法会倾向于探索更多节点,因为启发式函数不够紧
- 搜索空间变大,计算时间变长
- 严重时,可能找不到最优路径
4.3 如何避免高估代价——我的调优经验
嗯,这里要注意。对角线距离本身已经比曼哈顿距离精确了,但还不够。为什么?因为实际移动中,斜线移动的代价可能不是严格的√2。
我遇到过的情况是这样的:
有一次做仓储机器人项目,地面是环氧树脂,摩擦力比较小。机器人斜着走的时候,轮子打滑,实际走的距离比理论值多了5%。这时候如果用严格的√2,代价还是低估了。
所以我的建议是:
- 先用理论值 √2:大部分场景下够用
- 实测修正:让机器人实际跑一下,记录斜线移动的真实代价
- 微调系数:比如把 √2 改成 1.45 或 1.5,看效果
4.4 代码实现
直接上代码。这是我项目里用的一段,稍微简化了一下:
# 对角线距离计算
def diagonal_distance(start, goal):
dx = abs(start[0] - goal[0])
dy = abs(start[1] - goal[1])
# 斜线代价,可调参数
D = 1.0 # 直线代价
D2 = 1.414 # 斜线代价,理论值
# 核心公式
return D * (dx + dy) + (D2 - 2 * D) * min(dx, dy)
# 或者更直观的写法
def diagonal_distance_v2(start, goal):
dx = abs(start[0] - goal[0])
dy = abs(start[1] - goal[1])
# 先走斜线
diagonal_steps = min(dx, dy)
# 再走直线
straight_steps = abs(dx - dy)
return diagonal_steps * 1.414 + straight_steps * 1.0
我个人习惯用第一种写法,因为调参方便。把 D 和 D2 抽出来,改一个地方就行。
4.5 什么时候用对角线距离
| 场景 | 推荐距离 | 原因 |
|---|---|---|
| 四方向移动(上下左右) | 曼哈顿距离 | 不能斜走,曼哈顿就是精确的 |
| 八方向移动(可斜走) | 对角线距离 | 精确匹配移动能力 |
| 任意方向移动 | 欧氏距离 | 没有方向限制,欧氏最准 |
| 有障碍物的复杂环境 | 对角线距离 + 障碍物惩罚 | 需要额外处理 |
4.6 避坑指南
我曾经踩过一个坑,分享给你:
有一次做AGV调度,地图是网格化的,但机器人实际移动是连续的。我用对角线距离做A*,结果路径规划出来全是锯齿状的。为什么?因为对角线距离假设机器人可以完美走斜线,但实际场地里,斜线路径上可能有障碍物,机器人只能走折线。
后来我加了一个路径平滑的后处理步骤,才解决了这个问题。
- 对角线距离适合八方向移动,比曼哈顿更精确
- 公式:min(dx,dy)*√2 + |dx-dy|
- 实际项目中,斜线代价可能需要微调
- 高估代价会导致A*搜索效率下降,甚至找不到最优解
- 别忘了路径平滑——对角线距离规划出来的路径可能不够顺
最后说一句。对角线距离不是万能的。如果你的机器人是差速轮,可以任意方向移动,那直接用欧氏距离就行。但如果是四轮车、履带车,或者有方向限制的机器人,对角线距离就是你的最佳选择。
下一节,咱们聊聊欧氏距离的陷阱——为什么它有时候会低估代价,以及怎么处理。