【问题标题】:Simulating separation forces amount n bodies模拟分离力数量 n 个物体
【发布时间】:2014-07-03 02:16:47
【问题描述】:

我正在为在屏幕上四处走动的小生物编写模拟程序。我遇到的一个问题是它们有时会靠得太近——我认为解决这个问题的一种方法是有一定的阈值距离,当任何两个生物接近这个距离时,一种力量会将它们推开。

然而,在我实现这个之前,我想知道是否有任何已知的算法用于这个除了蛮力 解决方案。

我一直在研究几种不同的算法,其中一个值得注意的是 Barnes-Hut 算法,它在 时间运行 - 但是,我不确定这是否适用于这个问题。

感谢任何帮助

【问题讨论】:

    标签: performance algorithm simulation physics


    【解决方案1】:

    将您的身体网格化为树形结构,对 2D 使用四叉树,对 3D 使用八叉树。 O(n log n) 算法背后的想法是对每个身体进行 log n 比较,而不是 n 比较。如果您的身体被聚集成组,您可以计算一个簇的平均质量和位置。与其让该组中每个物体的力作用在一个物体上,不如说一个等效的伪物体的单个合力作用在另一个物体上。我相信这就是 Barnes-Hut 背后的理念。

    您将需要一个快速算法来识别您的集群,确定何时可以牺牲模拟精度来换取速度(可以将木星及其卫星组合为单个伪体来计算地球上的引力。它可能不能把木星和土星组合成一个伪体来计算地球上的引力)

    集群越大,准确度就越低。然而,更大的集群也意味着需要进行的身体比较更少。您可能还想优化可用于其他主体的聚类。将所有内行星与太阳分组可能可以计算所有外太阳系天体上的力。

    先从简单的O(n^2) 方法开始,然后再尝试复杂的O(n log n) 实现。准备好后,网络上有很多关于 n 体模拟的优秀文献。

    【讨论】:

      【解决方案2】:

      Barnes-Hut 和变体是执行此操作的常用方法,但我不会为您的用例实现完整的算法,因为它看起来有点矫枉过正。我可能只是将平面划分为一个正方形网格,比如 20 x 20,并为每个单元格维护一个集合,其中包含当前位于单元格内的所有生物。然后,对于每个生物,只需查看其单元格和 8 个(或侧面的 5 个或角落的 3 个)相邻单元格,并使用在一个单元格长度内下降到零的力。

      有一个明显的权衡 - 更精细的网格意味着需要考虑的生物对更少,但您必须更频繁地将它们从一个单元移动到另一个单元。小于力范围的单元格长度是没有用的,因为您不仅需要考虑 8 个邻居,还需要考虑超出力范围内的单元格。

      【讨论】:

      • 这种网格方法是否有一个特定的名称,或者是否有任何关于最佳网格大小的理论?
      • 关于矫枉过正的话题 - Barnes-Hut 算法会比暴力破解(即 10 个物体)花费的时间更长吗?
      • @fibonatic 我刚刚制作了网格,不知道它是否有名字。我首先想建议使用四叉树,但后来我认为它可能仍然是矫枉过正。假设对象 cells[object.X / cellSize, object.Y / cellSize] 的分布有点均匀是一个非常简单的解决方案,您需要非常好的理由 - 很多 对象和非常不均匀的分布 - 来证明使用某些树结构的复杂性是合理的。
      • @Sim 我不确定,但我的直觉是,朴素的算法可以胜过 Barnes-Hut 最多 50、100 甚至 500 个对象,但这真的很难猜。但我非常有信心 10 个对象会更慢。空间分区确实非常适合用于天真的解决方案或根本不可行的大型对象集合 - 数千、数百万和数千万个对象。
      • 顺便说一句,我认为更重要的想法是限制力的范围。 Barnes-Hut 近似于所有对象之间的力,但如果您没有模拟物理力场,并且您可以在一段距离后声明力为零,您可以忽略很多对象。划分空间只是一种方法,可以确定哪些对象的力可能不为零,哪些对象可以忽略,因为它们距离很远。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 2019-02-05
      • 1970-01-01
      • 1970-01-01
      • 2017-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多