我正在编写一个模拟n体重力系统的程序,根据每一步之间的“时间”步长,它的精度是任意的。现在,它可以非常快速地运行多达500个物体,但之后它变得非常慢,因为它必须通过一个算法来确定每次迭代在每对物体之间施加的力。这是复杂的n(n + 1)/ 2 = O(n ^ 2),因此它很快变得非常糟糕也就不足为奇了。我想最昂贵的操作是我通过取平方根确定每对之间的距离。因此,在伪代码中,这就是我的算法当前运行的方式:
for (i = 1 to number of bodies - 1) {
for (j = i to number of bodies) {
(determining the force between the two objects i and j,
whose most costly operation is a square root)
}
}
那么,有什么方法可以优化这个吗?任何花哨的算法可以重复使用过去迭代中使用的距离进行快速修改?有什么有损方法可以减少这个问题吗?也许忽略了x或y坐标(它是2维)超过一定数量的物体之间的关系,这是由它们的质量乘积决定的?对不起,如果这听起来像是在漫无边际,但是我能做些什么才能让它更快?我宁愿保持任意精确,但如果有一些解决方案能够以一定的精度降低这个问题的复杂性,我很想听听它。
感谢。
答案 0 :(得分:7)
看看this question。您可以将对象划分为网格,并使用这样的事实:可以将许多遥远的对象视为单个对象以获得良好的近似。单元格的质量等于它包含的对象质量的总和。细胞的质心可以被视为细胞本身的中心,或者更准确地说是它所包含的物体的barycenter。在一般情况下,我认为这给你O( n log n )性能,而不是O( n 2 ),因为您仍需要计算每个 n 个对象的重力,但每个对象只能单独与附近的对象进行交互。
假设你用 r 2计算距离 = x 2 + y < / i> 2 ,然后用 F = G m 1
答案 1 :(得分:3)
一个好的有损方法是运行clustering algorithm将主体聚集在一起。
有some聚类算法相当快,诀窍是不会在每次滴答时运行聚类算法。而是每隔C刻度运行一次(C> 1)。
然后,对于每个聚类,计算聚类中所有实体之间的力,然后为每个聚类计算聚类之间的力。
这将是有损的,但我认为这是一个很好的方法。
你必须摆弄:
所以它将成为速度与精确度的游戏,但至少通过这种方式,您将能够为某些速度增益准确地说明一些准确性 - 使用您当前的方法没有什么可以真正调整的。
答案 2 :(得分:1)
您可能想要尝试不太精确的平方根版本。您可能不需要完整的双精度。特别是如果您的坐标系的数量级通常是相同的,那么您可以使用截断的泰勒系列来快速估计平方根运算,而不会放弃太多的效率。