寻路,A星和速度惯性

时间:2015-12-13 04:39:26

标签: algorithm search path-finding a-star

有一个重复的问题,答案是我试图在这里实施并遇到困难。 How to do pathfinding when a unit has inertia?

我有一个带有障碍物的网格,计算机可以在四个基本方向上移动,并使用A-star或Djikstra算法实现路径寻找。

但是我还想添加“速度”,所以不是邻居move leftmove rightmove upmove down,而是{{1} },accelerate leftaccelerate rightaccelerate upaccelerate down。在每次移动时,保留前一次移动的速度,并添加加速度的增量。 do nothing费用为0,而Accelerate <dir>费用为1。

我尝试在一维的基础上使用A-star实现此功能,让它找到从Do nothing移动到(X=0, velocity=0)的路径。可用选项始终为(X=100, velocity=0)

找到成功完成任务的次优路径。加速仅两次,然后等待49次,减速一次,然后等待2次,再减速一次降落((Accelerate Cost=0, Decelerate Cost=0, Wait Cost=1)

最佳路径是:加速100次,等待一次,减速100次。

看起来A星可以处理(X,Y)网格中的寻路,其中X和Y是独立的,但是不能处理(X,Y)网格,其中Y也依赖于X.

关于如何修改A *或Djikstra的任何想法,还是我可以使用涉及惯性的替代寻路算法?

您可以在https://gist.github.com/meric/93540d1cff502684aac2

查看我的代码

取消注释第120行X=100, velocity=0)会生成最佳路径,因为它会隐藏“等待”选项,直到速度为100。

使用filter = function(current) return current.v > 99 end,

运行

1 个答案:

答案 0 :(得分:0)

Dijkstra / A-Star是基于图形的算法,经验证可用于任何图表。

  

看起来A星可以处理(X,Y)网格中的寻路,其中X和Y是独立的,但是不能处理(X,Y)网格,其中Y也依赖于X.

这是错的,A-Star和Dijkstra并不关心网格。由于简单,经常使用网格:底层图是隐式的(网格是节点,任何两个相邻图块之间都有一个顶点)。

图表表示

它是否适用于您的示例仅取决于您是否将系统正确表示为图形。

首先要注意的是:

  

我试图用A-star在一维基础上实现这个

这不起作用。 x=5, v=8处的船舶与x=5, v=-5处的船舶不是。因此,您的州由情侣 (x, v)表示。这不是一维问题。

要注意的第二点是:

  

Accelerate <dir>费用为0,而Do nothing费用为1。

你没有动力即将'很快'到达,只是尽可能少地使用Do nothing。因此:

  

最佳路径是:加速100次,等待一次,减速100次。

出于多种原因是错误的:

  • 考虑到惯性,一条最优(成本最低)的路径实际上是加速(10次),减速(10次)因为1+2+3+4+5+6+7+8+9+10+9+8+7+6+5+4+3+2+1 = 100而结束是 19步,成本为零< /强>
  • 另一条最佳路径是加速一次,交替(加减速)49次,减速。然后在~102步骤中达到,总成本为零
  • 您不需要许多更类似的“最佳”路径(零成本)。

要解决这个问题,只需给予客观时间(一个常数会做,或者可能是欧几里德距离?)的非零惩罚,无论采取什么行动。 (恰恰相反,我会将固定的“燃料”罚分设为1,以便在有几个可用时获得最节能的路径,但这是偏离主题的)

修复您的实施

如果您的 A-Star实施在我们知道存在成本较低的路径时会给出非零成本的结果,那么您就有一个需要修复的错误。

走X,Y

如果您计划在惯性的2D网格中导航,则需要4D节点表示(x,y,Vx,Vy)。

警惕两件事:

  • 4D空间可能会变得非常耗费内存。由于x和Vx已关联,因此您无法使用jump-point search来解决此问题。
  • 在有障碍物的4D中,碰撞检测将比传统的细胞基础运动更复杂。为了确保你没有跳过墙壁,使用天真的光线投射,或者(更好)使用Bresenham's Line Algorithm轮询顶点移动。