A*算法-介绍

来源:互联网 发布:卷睫盼 好听知乎 编辑:程序博客网 时间:2024/05/22 05:31

单个对象的运动(Movement)似乎很容易, 寻路(PathFinding)是复杂的。 为什么要寻路? 考虑以下情况:

该单位最初位于地图底部(start),并希望达到顶峰(goal)。 两点之间线段最短,所以它会向上运动,在扫描的区域中(以粉红色显示),没有任何东西表明该单位不应该向上移动,所以它继续向上。 靠近顶部,它检测到障碍物并改变方向。 然后,它绕着“U”形障碍物找到了一条红色虚线的路径。 相比之下,寻路器(PathFinding)将扫描更大的区域(以浅蓝色显示),但是发现较短的路径(蓝色),不会将单元发送到凹形障碍物中。

然而,您可以扩展运动算法来处理陷阱,如上所示。 要么避免产生凹陷的障碍,要么将其凸包标记为危险的(只有当目标在里面才能输入):

寻路器(PathFinding)可以提前计划,而不是等到最后一刻发现有问题。 有计划的寻路 和 根据运动算法进行响应 之间有一个权衡。 计划一般较慢,但效果较好; 运动通常更快,但会卡住。 如果游戏世界经常发生变化,未来的规划就不那么有价值。 我建议使用两者:大图,缓慢变化的障碍和漫长的路径使用寻路器(PathFinding); 局部地区,快速变化和短途径使用运动算法(Movement)。

Algorithms(算法)

我已经写了这一页的较新版本,但不是剩下的页面。 它具有交互式图表和示例代码。

计算机科学教科书的寻路算法用在数学意义上的图形上 - 一组具有连接它们的边的顶点。 平铺游戏地图可以被认为是一个图形,每个瓦片是一个顶点,并且彼此相邻的瓦片之间绘制的边框:

现在,我将假设我们正在使用二维网格。 如果您以前没有使用过图表,请参阅此引用。 然后,我将讨论如何从游戏世界中建立其他类型的图形。

大多数来自AI或算法研究的寻路算法都是为任意图而不是基于网格的游戏设计的。我们想要找到一些有利于游戏地图的特性的东西。

有一些我们认为常识的东西,但是不明白算法。

我们知道一些关于距离的东西:一般来说,由于两个东西相距较远,假设没有虫洞,需要很长时间才能从一个移动到另一个。

我们知道一些方向:如果你的目的地在东边,最好的路径是更可能走向东边而不是走向西方。

在网格上,我们知道有关对称性的东西:大多数时候,先移向北再移动到东,就是先向东移动再向北移。

这些附加信息可以帮助我们使寻路算法运行得更快。


Dijkstra’s Algorithm and Best-First-Search

Dijkstra的算法通过从对象的起始点开始访问图中的顶点来工作。 然后它再次检查最接近的尚未检查的顶点,将其顶点添加到要检查的顶点集合。 它从起点向外扩展到达到目标。 只要没有边缘有负成本,Dijkstra的算法就能保证从起点到目标的最短路径。 (我写的是“最短路径”,因为通常有多个等效的短路径。)在下图中,粉红色方块是起点,蓝色方块是目标,而蓝色区域显示Dijkstra算法扫描的区域。 最淡的瓦块是距离起点最远的地区,因此形成了探索的“边界”:

贪婪最优先搜索算法以类似的方式工作,除了它有一些对距离任何顶点多远的估计(称为启发式)。它选择最接近目标的顶点,来替代选择最接近起点的顶点。贪婪的最佳搜索不能保证找到最短的路径。然而,它比Dijkstra的算法运行得更快,因为它使用启发式函数来引导其快速到达目标。例如,如果目标在起始位置的南部,贪婪最佳搜索将倾向于集中在向南的路径上。在下图中,黄色表示具有高启发式价值(高成本达到目的)的节点,而黑色表示具有低启发式价值(低成本达到目标)的节点。 这表明,与Dijkstra的算法相比,Greedy Best-First-Search可以很快找到路径:

然而,这两个例子说明了最简单的情况 - 当地图没有障碍物时,最短路径确实是一条直线。 让我们考虑上一节所述的凹陷障碍物。 Dijkstra的算法会很吃力,但保证找到最短的路径:

再看贪婪最好的搜索,减少了工作,但其路径显然不是那么好:

麻烦的是,贪婪的最佳搜索是“贪心的”,并尝试朝目标迈进,即使它不是正确的道路。 既然只考虑到目标的成本,忽略到目前为止路径的成本,即使它的路径已经变得很长,它也会继续下去。

结合两者优点不是很好吗? A *于1968年开发,结合启发式方法,如贪婪最优先搜索和正式方法,如Dijsktra算法。这是一个有点不寻常的,启发式方法通常给你一个大概的方式来解决问题,而不保证你得到最好的答案。然而,A *建立在启发式的基础之上,虽然启发式本身并没有给你一个保证,A *可以保证最短路径。

The A* Algorithm

我将专注于A *算法。 A *是寻路的最受欢迎的选择,因为它相当灵活,可以在广泛的上下文中使用。

A *就像Dijkstra的算法一样,可以用来找到最短的路径。 A *就像Greedy Best-First-Search一样,它可以使用启发式引导自己。 在简单的情况下,它与贪婪最好的搜索一样快:

在具有凹陷障碍的示例中,A *找到与Dijkstra算法所发现的一样的路径:

其成功的秘诀在于它结合了Dijkstra算法使用的信息(有利于接近起点的顶点)和Greedy Best-First-Search使用的信息(有利于靠近目标的顶点)。 在谈论A *时使用的标准术语中,g(n)表示从起始点到任何顶点n的路径的确切成本,而h(n)表示从顶点n到目标的启发式估计成本。 在上图中,黄(h)表示远离目标的顶点,而深绿色(g)表示远离开始点的顶点。 A *从起点向目标移动时平衡两者。 每次通过主循环,它检查具有最低f(n)= g(n)+ h(n)的顶点n。

本文的其余部分将探索启发式设计,实现,地图表示以及与游戏中使用寻路相关的各种其他主题。 一些部分是完善的,其他部分是相当不完整的。

原文链接:http://theory.stanford.edu/~amitp/GameProgramming/AStarComparison.html

原创粉丝点击