【发布时间】:2011-12-28 05:39:15
【问题描述】:
我正在编写一个程序来模拟 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 坐标(它是二维的)超过一定数量的物体之间的关系,由它们的质量的乘积决定?抱歉,如果这听起来像我在漫无边际,但我能做些什么来加快速度吗?我宁愿保持任意精确,但如果有解决方案可以降低这个问题的复杂性,但会牺牲一点精确度,我很想听听。
谢谢。
【问题讨论】:
-
也许我很密集,但你不知道用 sqrt(x^2 + y^2) 得到距离,然后立即用 G*m1*m2/r^2 平方到得到力量?你不能完全去掉平方根吗?
-
@JamesMoughan 这行不通。因为你不想计算力的绝对值,而是力矢量。在这个公式中你得到
r_vec/Abs(r)^3 -
但这里的主要问题不是平方根的成本。这是该算法在对象数量上是二次方的。使用将对象组合在一起的近似值,您可以将其缩减为
n*log(n)或类似的东西。 -
你可以像詹姆斯所说的那样把平方根全部去掉。我刚刚测试了两种方式,结果相同。
标签: java optimization simulation gravity