Miz*_*zor 29 algorithm math distance path path-finding
我正在寻找一种算法用于我正在制作的赛车游戏.地图/关卡/轨道是随机生成的,所以我需要找到两个位置,即开始和目标,它们利用了大部分地图.
关于距离的计算,它不应该是缺乏更好词的"鸟道".如果它们之间存在墙(或其他阻挡区域),则A和B之间的路径应该更长.
我不确定从哪里开始,非常欢迎评论,并且建议的解决方案在伪代码中是首选.
编辑:对.在查看了gs的代码后,我又给了它一个镜头.我这次用C++写的,而不是python.但是,即使在阅读了Dijkstras算法,洪水填充和Hosam Alys解决方案后,我也没有发现任何重要的区别.我的代码仍然有效,但没有你想要运行的那么快.完整的消息来源是牧场.唯一有趣的线(我猜)是第78-118行的Dijkstra变体.
但速度不是这里的主要问题.如果有人能够指出算法中的差异,我真的很感激帮助.
Hos*_*Aly 10
假设地图是矩形的,您可以遍历所有边界点,并开始填充填充以找到起点的最远点:
bestSolution = { start: (0,0), end: (0,0), distance: 0 };
for each point p on the border
flood-fill all points in the map to find the most distant point
if newDistance > bestSolution.distance
bestSolution = { p, distantP, newDistance }
end if
end loop
Run Code Online (Sandbox Code Playgroud)
我猜这会是O(n^2)
.如果我没有弄错,那就是,长度和地图的宽度(L+W) * 2 * (L*W) * 4
在哪里,表示周长上的边界点的数量,是点的数量,并且假设洪水填充将访问最大点四次(从各个方向).由于等于点数,这相当于,应该优于2.(如果地图是正方形,则顺序为1.5.)L
W
(L+W) * 2
(L*W)
4
n
(L + W) * 8 * n
O(n
)
O(16n
)
更新:根据评论,因为地图更像是一个迷宫(比起我最初想的那个有简单障碍的地图),你可以在上面做出相同的逻辑,但检查地图中的所有点(而不是点上的点)只有边境).这应该是O(4n
2的顺序)
,这仍然比FW和Dijkstra都要好.
注意: 洪水填充更适合此问题,因为所有顶点仅通过4个边框直接连接.地图的广度优先遍历可以相对快速地产生结果(仅仅是O(n)
).我假设每个点可以在其4个邻居中的每一个的洪水填充中被检查,因此在上面的公式中的系数.
更新2:我感谢我收到的有关此算法的所有积极反馈.特别感谢@Georg 的评论.
PS欢迎任何评论或更正.
跟进关于Floyd-Warshall或Hosam Aly的简单算法的问题:
我创建了一个可以使用这两种方法的测试程序.这些是文件:
在所有测试案例中,Floyd-Warshall的速度要慢一些,可能这是因为有限的边缘量可以帮助这个算法实现这一目标.
这些都是时代,每次这个领域都是四胞胎,10个领域中有3个是障碍.
Size Hosam Aly Floyd-Warshall (10x10) 0m0.002s 0m0.007s (20x20) 0m0.009s 0m0.307s (40x40) 0m0.166s 0m22.052s (80x80) 0m2.753s - (160x160) 0m48.028s -
Hosam Aly的时间似乎是二次的,因此我建议使用该算法.Floyd-Warshall的内存消耗也是n 2,显然超过了需要.如果你知道为什么Floyd-Warshall如此之慢,请发表评论或编辑这篇文章.
PS:我很长时间没有写过C或C++,我希望我没有犯过太多错误.
我删除了我推荐Floyd-Warshall算法的原始帖子.:(
gs做了一个现实的基准并且猜测是什么,FW比Hosam Aly的典型地图尺寸的"洪水填充"算法慢得多!因此,即使FW是一个很酷的算法,并且比Dijkstra的密集图快得多,我不能再推荐它的OP问题了,它涉及非常稀疏的图(每个顶点只有4个边).
作为记录: