路径查找算法?


24

我首先在堆栈溢出中发布了这个问题,但是我猜那里没有人对视频游戏非常感兴趣...

所有类型的游戏中都使用哪些寻路算法?(无论如何,所有类型的角色都会移动)Dijkstra是否使用了很多?我认为不会,因为它实际上并未找出到达某个地方所需采取的步骤,对吗?如果我理解正确,它只会确定哪个对象是最近的。我并不是真的想编写任何代码;只是做一些研究,尽管如果您粘贴伪代码或其他内容,那也很好(我能理解Java和C ++)。我基本上是在总体上寻找路径查找的快速概述。

我知道A *就像在2D游戏中使用的算法。那太好了,但是不是基于网格的2D游戏又如何呢?帝国时代或Link的觉醒之类的东西。没有可导航的独特正方形空间,那么它们做什么?

3D游戏做什么?我已经读过这个令人毛骨悚然的http://www.ai-blog.net/archives/000152.html,听说它是该主题的权威,但是一旦设置了网格,它并不能真正解释如何操作,路径查找完成。如果他们使用的是A *,那么在3D环境中如何做?花键如何精确加工圆角?


2
我认为这个问题对于SE的问答格式来说太开放了。常见问题解答
John McDonald

1
您提到的游戏必须以一种或另一种方式将地图分解为A *的节点。,打破了传统工艺没有涉及方形网格,有很多方法可以做到这it.Check VID youtube.com/watch?v=nGC_kBCoHYc,一场精彩的比赛使得它让玩家不能告诉他们是什么实际上在幕后做。
XiaoChuan Yu

1
这里有很多问题,所以我不能真正写出答案,但是我会注意到Dijkstra确实返回了路径,并且大多数寻路算法都是多用途的。您将世界(2D或3D)转换为连接的图形,并在其上运行寻路算法。
Gregory Avery-Weir


1
请允许我大声疾呼。这个问题上了车SO 4个upvotes,比4 接近这里能源办票。我忍不住觉得这个网站的主持人太过激进了。当然,我可以看到问题是如何与FAQ中指定的准则相抵触的,但是引用这些准则是为了防止diminishing the usefulness of our site。这个问题已经被收藏了3次,这证明它对某些用户有用。因此,我忍不住要投票关闭它并冒着最终被删除的风险,这会适得其反。
David Gouveia,2012年

Answers:


62

一次有太多问题,因此仅要讨论其中一些主题就很难给出具体答案。我将答案一分为二,并尽我所能解决。我不认为这些列表中的任何一个都是完整的,但是它们是我记得的一些不同方法。


第1部分-寻路算法

对于初学者来说,有很多方法可以实现寻路,但并非所有方法都能返回最短路径,或者效率高甚至可靠。例如:

  • 原始方法不会“向前看”,并且每次只能执行一个步骤:

    • 随机退步 -朝目标方向一次迈出一步。如果遇到障碍物,请通过随机向后退一点,然后重试来尝试解决该问题。根本不可靠,并且会陷入多种情况。

    • 障碍物追踪 -其他方法类似于随机的后退,但不是随机地向后移动,而是在发现碰撞后开始在对象周围进行追踪,就好像您的右手粘在墙上并且必须移动来触摸它一样。一旦没有碰撞,继续朝目标方向移动。再一次会在很多情况下卡住。

  • 可以立即查找整个路径的方法:

    • 广度优先搜索 -通过一次访问每个子层来进行简单的图形遍历,找到路径时停止。如果该图未加权(即,每个相邻节点之间的距离始终相同),尽管效率不是很高,但它会找到最短路径。对于加权图,它可能不会返回最短路径,但始终会找到一条最短路径。

    • 深度优先搜索 -遍历图形的另一种方法,但并非逐层进行,算法尝试首先在图形中进行深入搜索。如果不限制搜索深度,则此方法可能会出现问题,尤其是在使用递归实现时,这可能会导致堆栈溢出,因此通常更安全地使用堆栈迭代地实现。

    • 最佳优先搜索 -类似于广度优先搜索,但使用启发式方法,优先选择最有前途的邻居。返回的路径可能不是最短的,但运行速度要比广度优先搜索快。A *是“最佳优先搜索”的一种。

    • Dijkstra的方法 -跟踪从开始到访问的每个节点的总成本,并使用它来确定遍历图形的最佳顺序。使用加权图并返回最短路径,但可能涉及很多搜索。

    • A * -与Dijkstra类似,但也使用启发式方法估算每个节点接近目标的可能性,以便做出最佳决策。由于这种启发式方法,A *可以更及时地找到加权图中的最短路径。

  • 然后是A *的变体(或一般来说是寻路优化),可以使其更快或更适应某些情况,例如(请参阅相关答案cstheory.SE上完整列表):

    • LPA * -与A *类似,但是在对图形进行较小更改时可以更快地重新计算最佳路径
    • D * Lite-基于LPA *,它执行相同的操作,但是假定“起点”是在进行图形更改时朝着终点移动的单位
    • HPA *(分层) -在不同的抽象级别使用多个图层以加快搜索速度。例如,较高层可以简单地连接房间,而较低层可以避免障碍。
    • IDA *(迭代加深 -通过使用迭代加深,与常规A *相比减少了内存使用。
    • SMA *(简化的内存限制) -仅利用可用内存来执行搜索。
    • 跳转点搜索 -在评论中归功于Eric!加快统一成本网格地图(link)上的寻路。

第2部分-搜索空间表示

最后解决这个问题:

我知道A *就像在2D游戏中使用的算法。那太好了,但是不是基于网格的2D游戏又如何呢?

这里有两个大误解!事实上:

  1. A *不在乎游戏是2D还是3D,这两种情况都同样适用。
  2. A *在任何图形表示下均可工作,因此它并不关心世界是否为网格。

因此,如果世界不需要是网格,那么您还可以通过其他方式来表示它吗?以下是对世界空间进行分区以进行寻路的方式的简要概述,其中大多数都适用于2D和3D:

  • 矩形网格 -将世界划分为规则的正方形网格,网格中的每个单元格都是图中的一个节点,两个无障碍节点之间的连接是一条边。

    在此处输入图片说明

  • 四叉树(Quadtree) -划分空间的另一种方法,不是将其划分为规则大小的单元格,而是将其划分为四个,然后将它们分别递归地划分为四个。添加第三个维度使其成为八叉树

    在此处输入图片说明

  • 凸多边形 -将可步行区域划分为相互连接的凸多边形网格。每个多边形都将成为一个节点,共享边即为图的边。例如,它们可以是三角形,有时甚至可以是艺术家在创建关卡资产时创建的网格。通常称为导航网格。看到这个链接。这是一个非常流行的导航网格构建工具集:Recast

    在此处输入图片说明

  • 可见点 -最常见的方法是将一个节点放置在障碍物的每个凸顶点的外部,然后连接可以互相看到的每对节点。检查此链接。节点不必一定是顶点,并且可以由设计人员在地图中手动放置。在那种情况下,该系统经常被称为航点图

    在此处输入图片说明


1
两个链接:1)Mikko Mononen已经完成了Killzone 3的路径查找工作,并且他有一个非常不错的博客,在该博客中,他记录了Recast(navmesh生成器)和Detour(路径查找工具包)的开发过程,这两个过程均在MIT的许可下使用,例如在Amalur王国:估算中。2)我认为,跳转点搜索是基于网格的路径查找中最近最大的发展之一。
埃里克(Eric)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.