我需要一些建议,为我的模拟找到一个足够的算法

时间:2011-10-20 07:41:40

标签: c++ algorithm scientific-computing

我正在做Monte-Carlo simulation一些粒子粒子。我的代码中有几个瓶颈,但主要的是在我做的一些尝试中,我需要更新所有粒子属性。代码是用c ++编写的,目前我有几个循环来实现它:
1.一个循环,用于存储所有粒子的旧属性并更新新属性 2. 2D循环互动。
3.另一个2D交互循环(我不能将它与第一个相结合) 4.存储的循环接受步骤/循环以拒绝该步骤。

我希望使用swap删除第4步,但我找不到这样做的方法。所有粒子都是一个具有多个名为propertiesnextPropertiesoldProperties的元素的类。你会怎么做?

3 个答案:

答案 0 :(得分:3)

听起来你可以使用double buffering。基本上,你会保留指向两个粒子对象数组的指针 - 称之为acceptedtrial。在试验开始时,将accepted数组上的粒子属性复制到trial数组上的粒子属性,并进行所需的任何修改。如果试用成功,那么您只需交换指针,以便以前trial数组成为accepted,反之亦然。

另外,您说只有某些的试用版涉及昂贵的更新。如果是这样,您可能会对fast variable draggingensemble updating等技术感兴趣。

答案 1 :(得分:0)

步骤#2和#3将是O(N^2),而#1和#4是O(N),所以你应该专注于那些。

如果您绝对需要在每对粒子之间进行计算,那么您无能为力。但最有可能的是,相距一定距离的粒子对彼此的影响可以忽略不计,或者您可能只需处理最近的k粒子(对于固定的k)。在这种情况下,octtree(或kd-tree,aabb tree或类似的东西)是减少成对计算次数的最佳选择。

特别是,您可能希望查看Barnes-Hut方法,该方法用于降低引力计算的复杂性。

答案 2 :(得分:0)

我认为主要的瓶颈是你的2D互动。如果您正在进行N ^ 2交互,您可能需要考虑是否可以使用平均场近似,基本上在单元格中拆分计算域,为每次迭代计算每个单元格的平均场,然后仅计算与同一细胞中的粒子相互作用,加上周围细胞的平均场校正。

Here您可以阅读有关此优化的更多详细信息以及何时相关