n身体模拟预期性能巴恩斯小屋

时间:2018-07-18 10:59:45

标签: java algorithm simulation physics

我首先使用蛮力进行了二维n体仿真,但是随后http://arborjs.org/docs/barnes-hut之后,我实现了Barnes-Hut逼近算法。但是,这并没有给我想要的效果。

例如:

Barnes-Hut-> 2000具尸体;帧时平均32毫秒和5000; 164毫秒

蛮力-> 2000机构;帧时平均31毫秒和5000; 195毫秒

这些值均已关闭渲染。

我是否正确地假设我没有正确实现算法,因此性能没有得到实质性的提高?

Theta当前设置为s / d <0.5。将此值更改为例如1确实可以提高性能,但是很明显为什么不推荐这样做。

单线程

我的代码大致如下:

while(!close)
    {
        long newTime = System.currentTimeMillis();
        long frameTime = newTime-currentTime;
        System.out.println(frameTime);
        currentTime = newTime;

        update the bodies
    }

在更新正文的函数中:

first insert all bodies into the quadtree with all its subnodes
for all bodies
    {
        compute the physics using Barnes-Hut which yields a net force per planet (doPhysics(body))
        calculate instantaneous acceleration from net force
        update the instantaneous velocity
    }

barneshut函数:

doPhysics(body)
{
    if(node is external (contains 1 body) and that body is not itself)
    {
        calculate the force between those two bodies

    }else if(node is internal and s/d < 0.5)
    {
        create a pseudobody at the COM with the nodes total mass
        calculate the force between the body and pseudobody

    }else (if is it internal but s/d >= 0.5)
    {
        (this is where recursion comes in)
        doPhysics on same body but on the NorthEast subnode
        doPhysics on same body but on the NorthWest subnode
        doPhysics on same body but on the SouthEast subnode
        doPhysics on same body but on the SouthWest subnode
    }
}

实际计算力:

calculateforce(body, otherbody)
{
    if(body is not at exactly the same position (avoid division by 0))
    {
        calculate force using newtons law of gravitation in vector form

        add the force to the bodies' net force in this frame
    }
}

1 个答案:

答案 0 :(得分:0)

您的代码仍然不完整(在SSCCE s上阅读),并且不完整代码的深入调试不是该站点的目的。但是,这就是我将如何确定错误(如果有的话)的下一步:

  • 仅时间 您担心的功能(让我们称之为barnes_hutt_update());而不是整个更新循环。将其与等效的非B-H代码进行比较,而不是与没有B-H的整个更新循环进行比较。这样可以进行更有意义的比较。
  • 您似乎已将s / d 0.5硬编码到算法中。不用理会它,当它设置得更高时,您应该能够注意到加速。如果将B-H设置为0,则其性能与单纯的非B-H实现非常相似。您知道要跳过多少个节点吗? 没有跳过的节点,没有加速。另一方面,跳过节点会在计算中引入小错误-您是否量化了这些错误?
  • 看看B-H在线的其他实现方式。 D3的force layout在内部使用它,并且可读性强。现有多个四叉树实现。如果您是自己建造的,它们可能不是最佳的(甚至是越野车)。除非您尝试边做边学,否则最好使用经过测试的库而不是自己动手做。
  • 减速可能是由于使用了四叉树,而不是由于加力本身。知道与B-H逼近本身相比,构建和更新四叉树需要花费多长时间,这很有用-因为在这种情况下,四叉树是纯开销。 B-H需要四叉树,但非B-H幼稚的实现则不需要。对于少量节点,天真会更快(但是随着您添加的越来越多,天真会变得越来越慢)。 随着您添加越来越多的实体,性能如何缩放?
  • 您是否正在创建和丢弃大量对象?通过使用memory pool,可以使算法避免相关的开销(是的,大量新闻+垃圾收集会导致速度显着降低)。