如何提高我的A*路径查找算法的性能?

我编写了一个A*路径查找算法,它可以找到穿过障碍物的路径,并且可以对角移动。我基本上是将链接中的伪代码实现为实际代码,并且使用了二进制堆方法来添加和删除开放列表中的项目。

使用二进制堆显著提升了性能,大约比我之前使用的插入排序算法快了500倍。

问题是,它仍然平均需要150万纳秒左右,也就是大约0.0015秒的时间。

所以问题是,我的计划是制作一个塔防游戏,每当我在地图上添加一个塔时,每个怪物的路径查找都需要更新。如果地图上有大约50个怪物,这意味着更新所有怪物的路径将需要大约0.0015 * 50 = 0.075秒。游戏的每一次更新(所有游戏内内容的更新)是每60分之一秒,也就是0.016秒,所以问题是更新路径所需的时间比更新一次的时间还长,这将导致严重的滞后。所以我应该怎么做呢?我需要找到一个更好的算法来排序开放列表,还是应该将路径查找任务分开,以便每次更新只执行X个路径查找任务,而不是全部执行?


回答:

与其从每个敌人开始搜索到检查点,不如从检查点开始向外搜索到所有敌人。这样,你只需要进行一次搜索,而不是50次。

更具体地说,只需从玩家开始进行广度优先搜索(或者,如果你的图是有权重的,可以使用Dijkstra算法,直到所有敌人都被覆盖。

你可以通过更改你的启发式函数EstimatedDistanceToEnd(即h(x)为到任何敌人的最小估计值,来调整这个策略以适用于A*,但如果敌人很多,这可能会比更简单的选项慢。启发式函数必须是一致的,这样才能生效。


此外,请确保你使用的是正确的平局处理标准

最重要的是,请记住,大多数游戏不需要每一帧都运行路径查找算法——通常每秒一次或两次,甚至更少,具体取决于游戏的需求。

如果这仍然太慢,你可以考虑使用D* lite来在后续搜索之间重用信息。但是,我敢打赌,运行一次广度优先搜索将足够快。

(摘自我在gamedev上对类似问题的回答)

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注