如何使用A-star(A *)找到最“自然”的直接路线

时间:2009-05-10 16:42:01

标签: artificial-intelligence path-finding a-star

我已经在AS3中实现了A *算法,除了一件事之外它的效果很好。 通常,生成的路径不会采用最“自然”或平滑的路径到达目标。 在我的环境中,物体可以对角地移动,因为它可以水平或垂直移动。 这是一个非常简单的例子;起点由S标记,结束点(或结束点)由F。

标记
 | | | | | | | | | |
 |S| | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
 |F| | | | | | | | |
 | | | | | | | | | |
 | | | | | | | | | |

正如您所看到的,在第一轮发现期间,节点[0,2],[1,2],[2,2]将全部添加到可能节点列表中,因为它们都具有分数N. 当我正在尝试决定继续使用哪个节点时,我遇到的问题就出现了。在上面的例子中,我使用possibleNodes [0]来选择下一个节点。如果我将其更改为possibleNodes [possibleNodes.length-1],我会得到以下路径。

 | | | | | | | | | |
 |S| | | | | | | | |
 | |x| | | | | | | |
 | | |x| | | | | | |
 | | | |x| | | | | |
 | | |x| | | | | | |
 | |x| | | | | | | |
 |F| | | | | | | | |
 | | | | | | | | | |
 | | | | | | | | | |

然后使用possibleNextNodes [Math.round(possibleNextNodes.length / 2)-1]

 | | | | | | | | | |
 |S| | | | | | | | |
 |x| | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
 |F| | | | | | | | |
 | | | | | | | | | |
 | | | | | | | | | |

所有这些路径都具有相同的成本,因为它们都包含相同数量的步骤,但在这种情况下,最明智的路径如下......

 | | | | | | | | | |
 |S| | | | | | | | |
 |x| | | | | | | | |
 |x| | | | | | | | |
 |x| | | | | | | | |
 |x| | | | | | | | |
 |x| | | | | | | | |
 |F| | | | | | | | |
 | | | | | | | | | |
 | | | | | | | | | |

是否有正式接受的方法使路径看起来更合理而不仅仅是数学上正确的?

5 个答案:

答案 0 :(得分:10)

您需要在启发式函数中添加一个Tie-breaker。这里的问题是有许多路径具有相同的成本。

对于有利于直接路线的简单连接器,您可以使用交叉产品。即如果S是起点而E是结束,并且X是算法中的当前位置,则可以计算SE和XE的交叉乘积,并在启发式中加上一个惩罚,它进一步偏离0(=直接路径) )。

在代码中:

 dx1 = current.x - goal.x
 dy1 = current.y - goal.y
 dx2 = start.x - goal.x
 dy2 = start.y - goal.y
 cross = abs(dx1*dy2 - dx2*dy1)
 heuristic += cross*0.001

另请参阅http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html#S12,这是一个关于A *的优秀教程。

答案 1 :(得分:4)

如果您想要看起来很自然的路径,则需要确保您的成本与笛卡尔坐标系上的长度相对应。这意味着对角线移动的成本应该是垂直或水平移动成本的sqrt(2)倍。

答案 2 :(得分:2)

您可以为每个方块的成本计算添加“控制工作量”。演员将尝试不转动或改变方向太多,因为这会增加路径的成本:

http://angryee.blogspot.com/2009/03/better-pathfinding.html

答案 3 :(得分:1)

如果我没记错的话,那就是在成本函数中添加一个额外的参数(对于相邻节点之间的每一步,或者你的情况下的正方形)惩罚转弯比正常情况稍微多一点(例如,对于数字移动而言,相对成本大于sqrt(2)。现在,在平滑路径和实际降低路线的最优性(延长路线)之间可能存在一条细线,但是,你无法以任何方式避免这种情况。您需要根据自己的应用程序进行特定的权衡,这只能通过测试来实现。

我相信在游戏开发网站上有一篇文章详细说明了如何做到这一点,但我现在似乎无法找到它。无论如何都要考虑你的成本函数,看看你得到了什么结果 - 我很确定这是你要走的路。

答案 4 :(得分:0)

什么更“明智”?直?如果算法要对它做任何事情,你需要正确量化它。

由于对角移动与水平/垂直移动一样便宜,因此根据A *可用的所有标准,所有路径都是等效的。如果你想要一个更“明智”的路径,你需要告诉算法一些路径比其他路径更合意,有效地将水平/垂直加权为比对角线“更好”。据我所知,这将改变你的环境参数。