我在高性能集群中从事理论化学工作,通常涉及分子动力学模拟。 我的工作涉及的问题之一涉及N维(通常N = 2-5)超​​球的静态场,测试粒子可能碰撞。 我正在寻找优化(读取:大修)我用来表示球体领域的数据结构,这样我就可以进行快速碰撞检测。 目前,我使用一个死的简单指针数组指向N元结构(中心的每个坐标加倍)和最近邻居列表。 我听说过oct和quad-trees,但是没有找到关于它们如何工作,如何有效地实现它,或者如何用一个快速碰撞检测的明确解释。 鉴于我的模拟大小,内存(几乎)没有对象,但周期是。

===============>>#1 票数:4

如何最好地解决您的问题取决于您未描述的几个因素: - 相同的超球面排列是否会用于许多粒子碰撞计算? - 超球体的大小是否均匀? - 粒子的运动是什么(例如直线/曲线),是受球体影响的运动? - 你认为粒子的体积是零吗?

我假设粒子不具有简单的直线运动,因为这将是找到线和点之间的最近点的相对快速的计算,这可能与找到线的哪个框的速度大致相同。与...相交(以确定要检查的n树中的位置)。

如果您的超球面位置对于大量粒子碰撞是固定的,那么计算voronoi分解/ Dirichlet曲面细分将为您提供一种快速的方法,以便稍后找到空间中任何给定点的哪个球体最接近您的粒子。

然而,要回答关于八叉树/四叉树/ 2 ^ n树的原始问题,在n维中,您将从包含您感兴趣的空间区域的(超)立方体开始。这将被细分为2 ^ n个超立方体如果你认为内容太复杂了。 这将继续递归,直到叶节点中只有简单元素(例如一个超球面质心)。 现在构建了n树,您可以通过获取粒子的路径并将其与外部超立方体相交来将其用于碰撞检测。 交叉点位置将告诉您接下来要访问的树的下一级中的哪个超立方体,并确定该级别上所有2 ^ n超立方体的交叉位置,然后向下,直到到达叶节点。 到达叶子后,您可以检查粒子路径与存储在该叶子上的超球面之间的相互作用。 如果碰撞已经完成,则必须从当前超立方体叶片中找到粒子路径的出口点,并确定它移动到下一个的超立方体。 继续,直到发现碰撞或完全离开整个边界超立方体。

退出超立方体时有效地找到相邻超立方体是该方法中最具挑战性的部分之一。 对于2 ^ n树,可以调整Samet的方法{1,2}。 对于kd-trees(二叉树),在{3}第4.3.3节中提出了一种方法。

有效的实现可以简单到将每个超立方体的8个指针的列表存储到其子超立方体,并且如果它是叶子则以特殊方式标记超立方体(例如,使所有指针为空)。

可以在Klinger&Dyer {4}中找到划分空间以创建四叉树(可以推广到n树)的描述

正如其他人所提到的,kd-tree可能比2 ^ n-tree更适合,因为对任意数量维度的扩展更为直接,但是它们将导致更深的树。 也可以更容易地调整分割位置以使用kd树匹配超球面的几何形状。 以上对2 ^ n树中的冲突检测的描述同样适用于kd树。

{1} 连接组件标签,Hanan Samet,使用Quadtrees期刊ACM第28卷,第3期(1981年7月)

{2} 由八叉树代表的图像中的邻居发现,Hanan Samet,计算机视觉,图形和图像处理第46卷,第3期(1989年6月)

{3} 凸壳体生成,连通分量标记和理论定义模型的最小距离计算,Dan Pidcock,2000

{4}使用常规分解的图片表示实验,Klinger,A。和Dyer,CR E,Comptr。 图形和图像处理5(1976),68-105。

===============>>#2 票数:1

听起来你想要实现一个kd树,它可以让你更快地搜索N维空间。 有一些更多的信息和链接到Stony Brook算法库的实现。

===============>>#3 票数:1

由于你的场是静态的(我假设你的意思是超球不移动),那么我所知道的最快的解决方案是Kdtree。
您可以自己制作,也可以使用其他人,如下所示: http//libkdtree.alioth.debian.org/

===============>>#4 票数:0

四叉树是二维树,其中在每个级别节点具有4个子节点,每个子节点覆盖父节点的1/4区域。

Oct树是一个三维树,其中每个级别一个节点有8个子节点,每个子节点包含父节点体积的1/8。 这是帮助您想象它的图片: http//en.wikipedia.org/wiki/Octree

如果您正在进行N维交叉测试,则可以将其推广到N树。

交叉算法的工作原理是从树的顶部开始,并递归遍历到与被测对象相交的任何子节点,在某些时候,您将获得包含实际对象的叶节点。

===============>>#5 票数:0

只要你可以通过它们的中心指定球体,八叉树就可以工作 - 它将点分为两个孩子的立方区域。 在八叉树数据结构中计算邻居将要求您进行球体相交立方体计算(在某种程度上比它们看起来更容易),以确定八叉树中的哪些立方区域在球体内。

查找最近的邻居意味着返回树,直到您获得一个包含多个填充子节点并包含所有周围节点的节点(这可确保查询获取所有边)。

从记忆中,这是球形立方体交叉的(有点天真)基本算法:

一世。 是多维数据集中的中心(这得到了同名的情况)

II。 立方体的任何角都在中心的半径r内(球体内的角落)

III。 对于立方体的每个表面(你可以通过计算中心所在表面的哪一侧来消除一些表面)计算出来(这是所有第一年的矢量运算):

一个。 表面的法线到达球体的中心

从球体中心到法线与表面平面的交点的距离(弦线平面与立方体表面平面)

C。 平面的交点位于立方体的侧面(与立方体相交的一个条件)

IV。 计算弦的大小(正常长度与球体半径之比的Cos ^ -1)

v。如果线上的最近点小于弦的距离并且该点位于线的两端之间,则弦与立方体的一个边相交(弦沿着其中一个边与某个立方体表面相交)。

略微模糊地记住,但这是我在使用octee数据结构(多年前)涉及球形区域的情况下所做的事情。 您可能还希望查看KD树,因为其他一些海报建议,但您的初始问题听起来与我所做的非常相似。

  ask by translate from so

未解决问题?本站智能推荐:

2回复

适用于Java中的Flocking Boids的2D空间数据结构

我正在进行植绒boids仿真,只是为了好玩,我想稍微优化一下。 需要工作的区域是在给定的boid附近找到boids。 我认为要做到这一点,某种适合任务的空间数据结构将是我最好的选择(请参阅此处并向下滚动一下。)。 无论我采用什么,我都会用Java从头开始实现自己。 这样我就可以学到更
5回复

哪种数据结构? LinkedList或Java中的任何其他内容?

我对我在Java程序中使用的数据结构有特定的要求。 它(数据结构)应该能够容纳大量数据(不固定),我的主要操作是在最后添加,并从头开始删除/读取(LinkedLists看起来很好)。 但偶尔,我也需要从中间删除,这就是LinkedLists太痛苦了。 任何人都可以建议我解决这个问题吗?
10回复

以下约束的最佳数据结构?

以下是我需要的数据结构的一些约束。 看起来没有一个共同的数据结构(我会提到我在下面想到的那些)都很适合这些。 任何人都可以建议一个我可能没有想到的吗? 我需要能够通过无符号整数键执行查找。 要存储的项目是用户定义的结构。 这些指数很稀疏,通常极其如此。 常规数组已
1回复

Angular 1.5和多重嵌套数据结构

我有一个类似此示例的嵌套结构: 如您所见,结构类似于目录-我有代表单位的对象,每个单位都有自己的节号,标题和带有小节的数组。 数据特征是我永远不知道我有多少节和多少嵌套子节。 我需要假设我可以用不同的配置获得大约2 000个对象(可能更多)。 另外,我无法预测最大嵌套级别,并且
2回复

选择python数据结构以加快算法实现

因此,我得到了大量的列表(大约200k)。 每个列表都包含数字0到27的子集。我想返回其中两个列表的长度乘积大于其他任何一对列表的长度乘积的列表。 还有另一个条件,即列表没有相同的数字。 我为此找到了一种算法(记不清来源,对于道具的非特异性表示歉意),该算法利用了数字0到27的总子集少
2回复

是否有适合此问题的数据结构或优化?

我有一个Node.JS服务器,我有一个字典(哈希/地图)(键是数字,值 - 数组)。 字典的每个元素都是一个ID(字符串)数组,并且有许多元素。 数组的每个元素在其数组中都是唯一的。 例如: let map = {2333:['id1', 'id2', 'id3', 'id4'], 1
1回复

用于查找大于或小于每个笛卡尔维度中的值的所有点的空间数据结构

我目前正在研究一个优化问题,该问题需要在所有基本方向上找到大于(或在某些情况下小于)特定点的所有点。 例如,在2D中,我可能需要找到满足条件的所有点: (例如 - 如果下图中的蓝点是(x *,y *),我需要蓝色虚线定义的框中的所有点)。 注意:我需要这是一个N维结构/搜索,因为
2回复

空间数据结构中的不同搜索方法

我正在尝试编写一个空间数据结构(例如KD tree或QuadTree ),给定一个点,它将找到x最接近它的点。 我上面提到的数据结构的问题是它们主要支持径向/区域搜索。 因此,他们将获得在给定点/节点的y的半径范围内的点。 改变这些结构来寻找我想要的东西会效率低下。 我假设我需要
1回复

C-完全复制数据结构的速度与部件

我正在研究Kruse,Leung和Tondo的“用C语言编写数据结构和程序”。 第2章第2章介绍了一个简单的数据结构(列表),随后要求读者为该结构编写两个不同的复制函数。 有问题的练习为E2,内容如下: 编写将一个列表复制到另一列表的函数(作为文本中定义的结构类型)。 使用以下方
2回复

最佳数据结构,用于在C ++中存储和搜索短语

我使用trys数据结构存储单词。 现在,我有一个要求,即在给定的段落中查找同一段落中是否存在某些短语。 这样做最有效的方法是什么? 短语总数不超过100。