有时,寻路在性能方面的限制因素,不是计算路径所需的时间,而是数百个单元的路径所占用的空间。
探测器需要运行算法的空间,以及存储路径的空间。
算法运行所需的临时空间(使用 A*,OPEN 和 CLOSED 集合)通常比存储结果路径所需的空间大。
通过将游戏限制为一次只计算一条路径,可以最大限度地减少所需的临时空间量。
此外,为 OPEN 和 CLOSED 集合选择数据结构可以最大限度地减少临时空间。
本节将重点关注最小化结果路径使用的空间。
地点 VS 方向
路径的存储形式可以是用位置,或是方向。
有点像数组和链表:
位置占用更多空间,但具有的优点是,可以轻松确定路径中的任意点的位置或方向,而无需遍历路径。
存储方向时,只能轻松确定方向;只能通过遵循指示的整个路径来确定位置。
在典型的网格图中,位置可以用两个16位整数存储,使每一步取32位。
然而,方向少得多,因此它们可以占用更少的空间。
如果单元只能在四个方向上移动,则每步只需2位;如果单元可以在六个或八个方向上移动,则每个步骤需要3位。
这两种方法都比在路径中存储位置节省了大量的开销。
Hannu Kankaanpaa 建议您可以通过存储相对方向(“向右转60度”)而不是绝对方向(“向北”)来进一步减少空间需求。
对于某些类型的单位,某些相对方向可能没有意义。
例如,如果你的单位向北移动,下一步就不太可能向南移动。
在六边形地图游戏中,您只有五个有意义的方向。
在某些地图上,也许这些方向中只有三个(直线,左边 60 度,右边 60 度)有意义,但在其他地图上,向右转120度可能是一个有效的移动(例如,当走上陡峭的山路时之字形)。
路径压缩(Path compression)
一旦找到路径,就可以以某种方式压缩它。
可以使用通用压缩算法,但这里不再讨论。
特定于路径的压缩算法可用于缩短基于位置的路径或基于方向的路径。
在决定之前,请查看游戏中的典型路径,以确定哪种压缩效果最佳。
此外,考虑易于实现(和调试),代码的大小,以及它是否真的重要。
如果您有 300 个单位的限制,并且任何时候只有 50 个步行,并且路径很短(100 步),则总内存需求可能只有 < 50k,并且不值得担心压缩。
位置的存储
在某些地图中,主要影响路径的因素是障碍物而不是地形。在这种地图中,路径中可能存在许多直线段。
如果是这种情况,则路径需要仅包含那些直线段的端点。
运动包括检查路径上的下一个点并沿着直线向它移动。
方向的存储
当存储方向时,可能出现连续多次遵循特定方向的情况。
您可以利用该常用模式在较小的空间中存储路径。
存储路径的一种方法是存储方向和数字,该数字指示单元应该朝该方向移动多少次。
与位置存储的优化不同,如果连续多次不采用方向,则此优化会使事情变得更糟。
此外,对于许多直线,对于位置进行压缩有用,而对于方向压缩则不是,因为线可能不与行走方向一致。
通过相对指示,您可以消除“继续前进”作为可能的方向。
Hannu Kankaanpaa 指出,使用八方向地图,你可以消除前进,后退和135度左右转弯(假设你的地图允许它),然后你可以只用 2 比特来存储每个方向。
存储路径的另一种方法是使用可变长度编码(variable length encoding)。
我们的想法是使用单个比特(0)进行最常见的步骤:直行。
使用 1 标记转弯,并按 1 乘以一些位来表示转弯。
在四方向地图中,您只能向左或向右转动,因此您可以使用 10 表示左,11 表示右。
可变长度编码更通用,并且可以比混合路径的行程长度编码更好地压缩,但对于长直路径则不能。
使用(方向,长度)对来记录行程,可以将(北,直六步,左转,直三步,右转,直五步,左转,直两步)表示为 [(NORTH,6),(WEST,3),(NORTH,5 ),(WEST,2)] 。
如果每个方向是 2 比特并且每个距离是 8 比特,则该路径需要 40 比特来存储。
对于可变长度编码,每步使用一位,每转使用两位 - [ NORTH 0 0 0 0 0 0 10 0 0 0 11 0 0 0 0 0 10 0 0] - 总共24位。
如果初始方向和每个转弯意味着一步,则每回合可以保存一位,从而产生 20 位来存储路径。
但是,较长的路径使用可变长度编码占用更多空间。
使用(方向,长度)对,(北,直走,两百步)是 [(NORTH,200)],共 10 位。
具有可变长度编码的相同序列是 [ NORTH 0 0 ...],共 202 位。
计算航路点
航路点是沿路径的一个点。
在路径寻找之后,后处理步骤可以将多个步骤折叠成单个路点,通常在路径改变方向的地方或在城市的主要位置处,而不是沿途存储每个步骤。
然后,运动算法将遵循航路点之间的路径。
受限的路径长度
鉴于地图条件或顺序可能会发生变化,因此存储长路径可能没有意义,因为在某些时候路径的其余部分可能没有任何用处。
可以在路径的开头存储固定数量的步数,然后在几乎遍历时重新计算路径。
该方法允许控制每个行走单位使用的数据量。
总结
路径可能占用游戏中的大量空间,特别是路径很长并且存在许多行走单位时。
路径压缩,航点和信标通过在少量数据中存储更多的步骤来减少空间需求。
航点依赖于直线段,因此我们仅存储端点,而信标依赖于预先在地图上的特殊标记位置之间计算的众所周知的路径。
如果路径仍占用太多空间,则路径长度可能会受到限制,从而导致经典的时空权衡:为了节省空间,信息可能会被遗忘并在以后重新计算。