Barnes-Hut算法

加速暴力方法解决n-体算法的一个重要思想是把临近的体分组并且把它们近似看作一个整体。如果体直接足够远,可以通过使用质心来近似重力效果。一组体的质心是组中所以体的位置的平均值,体的质量作为权重。比如,如果两个体的位置为(x1,y1)和(x2,y2),重量是m1和m2.则它们组合的体的质量是m=m1+m2,位置是(x=(x1*m1+x2*m2)/m , y=(y1*m1+y2*m2)/m)

Barnes-Hut算法是一种巧妙的策略来组合足够近的体。它递归的把一组体通过把他们存储在quad-tree来分组它们。

quad-tree类似于二叉树除了没个节点有4个子节点(一些节点可能为空)。每个节点代表了二维空间的一个区域。

根节点代表了整个空间,它的四个子节点整个区域的4个象限。就像下图所示,空间被递归的划分为4个象限直到

每个区域只包含0到1个体


每个根节点表示一个体。每个中间节点表示它下面的子节点组成的一组体,并且储存了这组体的质心。下图是一

个有8个体的例子:


从根节点开始,搜索树的节点来计算一个体的净力。如果一个内部节点的质心足够远离体,把这部分树包含的多

个体近似为一个体,它的位置是整组体的质心,重量是整组体的总重量。这个算法速度快的原因是我们不需要对组内的

每个体做单独的搜索查询。

如果内部节点离体不够远,循环访问它的每个子树。通过计算s/d来判断一个节点是否足够远,s是内部节点表示区

域的宽度,d是体与节点质心的距离。然后计算比较结果和阈值θ。如果s/d < θ, 表明内部节点充分的远。通过调整参数θ

我们可以调整算法的速度和精度。通常来说,实际使用中我们设定θ=0.5。注意,如果θ=0,那么没有内部节点被视为一

个体,整个算法就等同于暴力算法了

建立Barnes-Hut树

我们通过一个体一个体插入来搭建Barnes-Hut树。使用如下的递归程序来把体b插入到节点为x的树中:

  1. 如果节点x不包含任何体,把体b插入到x下面。
  2. 如果节点x是中间节点,更新x的质心和总质量。递归插入b到适当的象限中。
  3. 如果节点x是叶节点,并且包含体c,那么在同一个区域里有两个体b和c。创建4个子节点来划分这个区域并且递归的插入b和c到适当的象限。因为b和c还是有可能在同一个象限区域, 需要继续做区域的划分。最后更新x的质心和质量
下面是一个例子有5个体的例子。下面的例子中,我们约定成俗的把从左到右的分支分别代表西北、东北、西南、东南四个象

限。随着体的插入,树的变化如下图:


根结点包含了所有5个体的质心和总质量。中间节点包含了体b、c、d的质心和总质量。

计算作用在体上的受力

从树的根节点开始,使用如下的递归程序来是计算作用在体b上的净力:
  1. 如果当前节点是叶节点(并且体不是b),计算它作用在b上的力,把结果添加到b的净力。
  2. 否则,计算比率s/d。如果s/d < θ,把这个内部节点当作一个体,并计算它作用在b上的力,把结果添加到b的净力。
  3. 否则,在此节点的子节点上递归运行此程序
下面是一个例子,计算作用在体a上净力。从中间节点-根节点开始。它表示了a、b、c、d、e、f这6个体的质心,
他们的质量分别是1、2、3、4、5、6kg。
净力计算过程如下:
  • 最初访问的是根节点。比较体A和节点的质心(白色小点),比率s/d=100/43.1>θ=0.5,所以我们继续计算根结点的子节点

  • 第一个子节点是a本身。一个节点不会作用力在自身,所以我们什么都不做

  • 这个节点表示空间的东北象限,包含了b、c、d、e的质心。现在s/d=50/60.7>θ所以我们继续递归的计算该节点的第一个非空子节点。

  • 这个节点还是一个内部节点,表示它的父节点的东北象限,包含了b、c、d的质心,现在s/d=22/66.9<θ。把这个内部节点当作一个体来计算作用在体a上面的力。

  • 这一个节点是体e。这是一个叶节点,我们直接计算a和e之间的作用力

  • 检查了这一级的所以节点,我们移动到父节点的下一个兄弟节点,也就是体f。它也是叶节点,我们直接计算f、a直接的作用力


  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值