查找“ Granola Bar”状结构总质量的算法?


19

我是行星科学研究员,我正在研究的一个项目是土星环的N体模拟。这项特定研究的目的是观察粒子在其自身重力作用下会聚在一起,并测量其总质量与细胞中所有粒子的平均速度之间的关系。我们试图找出这是否可以解释卡西尼号航天器在土星夏至期间所做的一些观察,当时观察到大型结构在接近边缘的环上投下了阴影。以下是任何给定时间步长的屏幕截图。(每个粒子的直径为2 m,模拟单元本身的宽度约为700 m。)

土星环模拟的_N_体单元,其中的粒子显示为黑色背景上的微小阴影球。

我正在使用的代码已经在每个时间步上吐出了平均速度。我需要做的是找出一种方法来确定团块中的粒子质量,而不是它们之间的杂散粒子。我知道每个粒子的位置,质量,大小等,但是我不容易知道,例如,粒子30,000-40,000与102,000-105,000构成了一条对人眼来说很明显的链。

因此,我需要编写的算法必须是具有尽可能少的用户输入参数(用于可复制性和客观性)的代码,该参数将遍历所有粒子的位置,找出哪些粒子属于团块,然后计算质量 如果它可以针对“每个”丛集/链条(而不是单元格中的所有内容)做到这一点,那将是很好的,但是我认为我实际上并不需要将它们分开。

我唯一想到的是进行某种N 2距离计算,在该计算中,我将计算每个粒子之间的距离,例如,如果最接近的100个粒子在一定距离内,则该粒子将被视为粒子的一部分。簇。但这似乎很草率,我希望您的CS人员和程序员可能知道更优雅的解决方案?


使用“我的解决方案”进行编辑: 我要做的是采取一种最邻近/集群方法,并首先执行quick-n-dirty N 2实现。因此,取每个粒子,计算到所有其他粒子的距离,是否在一个簇中的阈值是在d距离内是否有N个粒子(不幸的是,必须先验设置两个参数,但是正如某些人所说的那样)回应/评论,我不会因为没有其中一些而逃脱。

然后,我通过不对距离进行排序而加快了速度,仅执行了N次搜索,并为d中的粒子增加了一个计数器,然后加快了6倍的速度。然后添加了“愚蠢的程序员树”(因为我知道几乎与树代码无关)。我瓜分模拟细胞成网格的一组数(最好的结果,当网格大小≈7 d)其中,主栅线与该单元格,一个网格由一半在偏移Xÿ,和另外两个是通过胶版1/4 in± x和± y。然后,代码将粒子划分为网格,然后每个粒子N只需要计算到该单元格中其他粒子的距离即可。

从理论上讲,如果这是一棵真正的树,我应该得到N * log(N)的阶数,而不是N 2的速度。我介于两者之间,对于50,000粒子的子集,速度提高了17倍;对于150,000粒子的单元,速度提高了38倍。第一次12秒钟,第二次53秒钟,500,000个粒子的电池460秒钟。这些速度与代码向前运行1个模拟代码所花费的时间相当,因此在这一点上是合理的。哦,而且它是全线程的,因此它将占用尽可能多的处理器。


3
我对这方面的知识不是特别了解,所以我自己几乎无法提供任何帮助,但是您是否阅读了Wikipedia上有关聚类分析的文章?这似乎是一个非常活跃的研究领域。
科尔·坎贝尔

我对集群代码(至少是DBSCAN之类的东西)保持警惕,因为我认为它会“跟随”我从视觉上知道不是集群的一部分但在算法上可能属于的细线。我确实有使用DBSCAN类型代码的经验,因为我将其用于其他工作,研究了陨石坑。
Stuart Robbins

1
几乎可以肯定,任何识别这样的链的代码都会带有某种“敏感度”设置。
罗伯特·哈维

2
同意 这里真正的困难是“团块”不是一个明确定义的术语。归根结底,您将不得不使用某种聚类分析算法(实际上,您提出的解决方案已经是),也许还要结合某种降噪措施。
科尔·坎贝尔

2
如果您在图片上画出有效的团块(可能是无效的团块),可能会有所帮助
jk。

Answers:


3

我的第一个建议是将您的问题分解为两个问题:首先,确定您想要的东西,然后确定如何有效地获得您想要的东西。您无法有效地获得尚未定义的内容。我将在此答案中提出一些想法,以帮助您找到此定义。我建议您首先对自己喜欢的想法进行低效的实现,将其应用于一些不太大的数据集,手动评估结果,修改定义并重复(可能在这里问另一个问题),直到满意为止您的定义。之后,我建议您问另一个问题,即如何有效地计算定义的结果(如果仍然需要帮助)。

因此,让我们看一下与我们的“链”的直观想法对应的内容。您的线束似乎由大致均匀分布的点组成,尽管您应通过制作(原始数据集的)放大图片进行检查-图片的分辨率太低,无法确定这些点实际上大致均匀分布。我假设他们是这个答案。

最初的想法可能是查看每个点的最近邻居。让我们选择一个点X,将其称为最接近的点Y,并将D设置为X和Y之间的距离。然后,我们看一下X周围的圆C,其半径为D * A,其中A为调整参数,例如A = 3。如果X是链的一部分,我们期望对于C中的每个点Z,从Z到其最近的邻居W的距离都与D大致相同。如果它短得多,则说比A大(或者说其他一些参数) B)然后,X显然比彼此更接近而不是X的点,因此X可能不是链的一部分。

但是,此标准不完整。它仅提供了一个标准来检测点密集的区域与点密集的区域之间的“边界”。我们仍然必须将点聚集在一起。

您的图片中有一项功能表明这并不简单。在图片的右下角,有一个相对较大的区域,带有很多杂散点。这些杂散点本身是大致均匀分布的,因此,如果我们要删除它周围的链中的所有点(以及所有其他点),那么我们将期望有任何链检测算法将这组杂散点标记为链!因此,在创建集群时我们需要小心。

一个想法可能是执行以下操作。我们将在这些点上绘制图形,其中顶点是点,边表示两个点具有相似的密度。对于每一点,我们都会检查上述标准。如果检出,则将X的边连接到C中的所有点。如果不检出,则不添加任何边,并将X标记为“杂散”。在完成每一点之后,我们考虑连接的组件集。这些应该由单个(就您的图片而言,但其他数据集可能具有多个)连接的组件组成,这些组件由线中的所有点组成,加上(可能很多)由单个杂散点和这些“杂散线”组成的更多组件。但是,这些杂散链中的点被标记为“杂散”,因此您可以简单地忽略包含点的所有组件,这些点已被标记为“杂散”。

这种想法的危险在于,您可能具有以下特征:随着沿线的移动,线的密度逐渐降低,直到密度如此之低,以至于它只是一组杂散点。由于我们的标准是“本地”,因此它可能无法检测到并将这些杂散点标记为链的一部分。我不确定这是否会成为问题:我猜大多数杂散点都应该被该标准捕获,因为密度的变化在您的图片中似乎非常突然。

如果确实发生此问题,则可以尝试采取其他方法,而不只是取出连接的组件。对于每个点X,我们计算到其最近邻居D(X)的距离。我们从最小D(X)开始并执行BFS(或DFS,顺序无关紧要)。我们添加任何D(Y)不比我们开始的D(X)大很多(通过可调因子)的点Y。如果我们确实遇到一个点Y,该点Y的D(Y)太大,我们将删除边(X,Y),将​​Y标记为“杂散”,并像我们从未在BFS中访问Y一样进行操作。如果调整正确,应该可以避免上述问题。

解决此问题的另一种方法是局部处理:您可以做一个BFS并跟踪遇到的最低D(X)(我用D(X)来衡量一个点周围的密度),最多可以说10之前的BFS,如果遇到的Y的D(Y)比此D(X)大得多,我们将执行与我提供的其他(潜在)解决方案相同的操作。

免责声明:以上所有想法都是我当场想到的,我真的不知道是否曾经研究过这个特殊问题,所以我可能只是在胡说八道。只需尝试一下听起来很明智的想法(无论是我的想法还是您自己的想法),然后找出它们是否确实可行,然后集中精力高效地实施它们即可。


2

使用模块化分解,您可以创建一棵包含所有粒子的树,而叶子和上层节点将它们聚类。基于该树,您可以定义应用于从根到叶向下的每个节点的度量。当测量达到用户定义的阈值时,可以停止向下遍历。一种这样的测量可以是簇中所有粒子的凸包的密度。


1

我认为您正在追求机器学习聚类算法。

Python SciKit学习工具包的本页包含建议您使用DBSCAN算法(Wikipedia)的图片。看起来很理想,因为它的输入参数是邻域大小,而其他大多数聚类算法都需要聚类的数量,而您事先不会知道。

Ester,M.,HP Kriegel,J.Sander和X.Xu,在俄勒冈州波特兰举行的第二届国际知识发现和数据挖掘国际会议论文集中,“基于噪声的大型空间数据库中发现簇的基于密度的算法” ,AAAI出版社,第226-231页。1996年


0

我一直在考虑这个问题。我不是物理学专家,所以请多多包涵。

似乎不是颗粒之间的距离才可以确定团块。重力场是否重叠。

取一个粒子P,并确定哪些其他粒子具有重叠的重力场。

然后采取其中之一,做同样的事情。您的目标不是找到团块中的所有粒子,而是找到其边界。

重复此过程,直到找到所有块。

现在回去确定团块的质量。您将消除杂散粒子,并且可以使用丛集边界找到质量。

我不确定这是否有帮助,但这只是我能想到的。


什么是重力场
大卫·考登

0

在每个时间步结束时,您都可以将数据转换为图形,计算最小生成树,然后开始删除超过特定阈值的边。那应该给你团块,并提供一种简单的方法来枚举每个团块中的粒子。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.