【问题标题】:Optimizing an n-body gravitational attraction algorithm优化 n 体引力算法
【发布时间】:2016-09-22 00:21:47
【问题描述】:

我正在编写一个二维原行星盘的模拟,而现在,最耗时的代码是计算引力。这是我目前正在使用的代码。

for(int i=0; i<particleCount; i++){
    if(boolArray[i]){    //boolArray is linked with particleArray, false means the linked particle has collided with another particle and no longer exists
        double iX = particleArray[i].getXPosition();
        double iY = particleArray[i].getYPosition();
        double iM = particleArray[i].getMass();
        for(int j=0; j<particleCount; j++){
            if(i!=j&&boolArray[j]){
                double rX = iX-particleArray[j].getXPosition();
                double rY = iY-particleArray[j].getYPosition();
                double rT = Math.sqrt(rX*rX+rY*rY);
                double rF = rT*rT*rT;
                double fT = -constantGravity*iM*particleArray[j].getMass()/rF;
                particleArray[i].updateForce(rX*fT, rY*fT);
            }
        }
    }
}

有人对如何加快速度有任何想法吗?我认为 sqrt 在

double rT = Math.sqrt(rX*rX+rY*rY);

是最大的罪魁祸首,但我不确定我是否能摆脱它。

编译就绪的代码可以在https://github.com/quietsamurai98/2D-Accretion-Simulation/tree/Trails-png找到

【问题讨论】:

  • Java 对 sqrt 函数使用 Smart Power 算法,其复杂度为 O(log n),速度很快。这不是延迟的原因
  • 您是否考虑过在同质区域(灰尘...)中使用扇区而不是粒子?这应该会大大降低物体的数量,精度会稍微低一些,但是如果您意识到离散积分与现实相去甚远......所以更多的拉伸精度应该不会产生太大的影响。为了确保您应该在几次迭代后将结果与展位方法进行比较,它们应该是 +/- 相同的

标签: java arrays algorithm optimization physics


【解决方案1】:

您为每对点计算两次。 试试这个。

for (int i = 0; i < particleCount; i++) {
    if (boolArray[i]) { // boolArray is linked with particleArray, false
                        // means the linked particle has collided with
                        // another particle and no longer exists
        double iX = particleArray[i].getXPosition();
        double iY = particleArray[i].getYPosition();
        double iM = particleArray[i].getMass();
        for (int j = i + 1; j < particleCount; j++) {
            if (boolArray[j]) {
                double rX = iX - particleArray[j].getXPosition();
                double rY = iY - particleArray[j].getYPosition();
                double rT = Math.sqrt(rX * rX + rY * rY);
                double rF = rT * rT * rT;
                double fT = -constantGravity * iM * particleArray[j].getMass() / rF;
                particleArray[i].updateForce(rX * fT, rY * fT);
                particleArray[j].updateForce(-rX * fT, -rY * fT);
            }
        }
    }
}

【讨论】:

  • 这绝对有帮助!
【解决方案2】:

您还可以使用四叉树(或 3d 的八叉树)。然后,您计算同一单元格内每个物体的重力,然后为每个外部单元格计算单元格内的质量总和,并计算该单元格中心与所述质量的重力。这会损失精度,但如果使用平衡良好的四叉树和非常多的 N-Bodies,看起来会非常逼真。 https://en.wikipedia.org/wiki/Barnes%E2%80%93Hut_simulation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    • 2020-04-10
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多