是否需要在循环的每次迭代中重新创建Barnes Hut Tree

时间:2013-06-11 16:45:50

标签: algorithm simulation physics game-physics

我正在编写一个应用程序,它需要在几百个不断运动的粒子之间进行n体模拟。该应用程序具有实时要求,因此执行模拟的算法需要很快。

我已就此问题进行了大量研究,并得出结论:Barnes Hut算法最适合我的需求,对于大粒子集来说似乎非常有效。

http://arborjs.org/docs/barnes-hut给出了关于算法如何工作的非常明确的解释,但正如标题所暗示的,我想知道是否需要为每次迭代重新创建树,考虑到模拟中使用的粒子总是动态地运动。如果树确实需要重新创建,那么如何以最有效的方式(在处理能力和内存方面)来做到这一点。

2 个答案:

答案 0 :(得分:2)

通常使用基于动作的索引,在移动发生后索引没有“更新”,您必须重建整个索引。

Barnes Hut Tree是相同的,必须重建。这是我在网上找到的example,其中包含该流程的代码大纲。

这是为KD-Tree之类的东西进行大量优化的原因之一,我相信Barnes Hut也是如此。此外,我确信有动态更新的研究,但大多数时候这些实现比简单的重建要困难得多。

答案 1 :(得分:0)

回答这个问题的时候已经很晚了。猜猜我从来没有解决过这个问题。但不是我现在已经调查了一段时间,我可以分享一些见解。 @greedybuddha所说的内容大多是正确的,但它们是防止每一步完全创建树的技巧和技巧。像往常一样,这些技术需要有自己的开销(内存占用等)和必要的权衡。此外,可能无法在所有情况下应用它们。

  1. 预先分配足够的内存来处理给定深度的八叉树。仅在所有时间步长完成时才释放内存。例如,假设您要使用的所有n体输入数据集,您知道您的八叉树将永远不会超过10的深度。在这种情况下它很容易弄清楚八叉树可能有多少个最大节点(通常是几何级数)。通过对每个八叉树节点进行一些簿记(每个节点的有效子索引),很容易重用此缓冲区来填充八叉树节点,而无需每隔一步分配/解除分配八叉树节点。显然,这里可能的开销是你可能浪费了大量内存但是你通过不在每个时间步执行分配/释放来获得性能 通常限制八叉树数量的方法是允许每个叶子节点有多个实体(八叉树的最后一级或八叉树网格的最小单元尺寸)

  2. 仅在需要时创建新的八叉树:可以考虑八叉树在一些时间步长(突发)时间内没有变化的情况,然后它会发生变化,模式重复。只有当物体位置在一个时间步长脉冲上变化不明显时才会发生这种情况,使得在该爆发期间八叉树结构保持不变。在什么情况下身体会缓慢移动 - 当所选择的时间步长非常小时,施加在身体上的力和初始动量很小。如何动态地弄清楚这样的爆发是一个难题。这是一个更棘手的技术,我不知道最简单的方法是什么。这需要对时间步长粒度,物体的初始速度/加速度以及物体所处理的力的种类有所了解。