K-D Tree vs R-Tree用于小型动态数据

时间:2014-02-01 04:02:01

标签: java kdtree r-tree

我一直在阅读几篇关于K-D树与R树的SO帖子,但我仍然对我的具体应用有一些疑问。

对于我的Java应用程序,我想保留相对较少的空间数据点(几十万)。关键是数据插入不会被批量加载,而是经常和逐步插入。我还要提一下,我将在空间域的子区域上执行大量的周期性范围查询。

我已经读过K-D Trees通常不支持增量构建,并且R-tree更适合这种情况,因为它们保持平衡状态。

但是,在查看此处建议的解决方案后: Java commercial-friendly R-tree implementation?

我没有发现这些实现很容易用于返回范围搜索中的点列表。但是,我发现:http://java-ml.sourceforge.net/有一个非常好的K-D树实现,它可以快速运行,并且在一组测试点(~25K)上优于标准阵列存储。另外,我已经读过R树在处理点时存储冗余信息(因为一个点是min = max的矩形)。

由于我使用较少数量的点,两个结构之间的差异是不是比重要的,例如,如果我使用的是存储数百万个点的数据库应用程序?

提前致谢!

2 个答案:

答案 0 :(得分:2)

R-tree无法存储点是不正确的。它们被设计为支持矩形,并且需要在内部节点处这样做。但是良好的实现应该在叶级别存储点,并且在那里大致具有双倍数据容量。

您可以简单地存储点,并将公开它们作为“矩形”公开,其中min = max为树管理代码。

您的数据不小。小就像100个物体。对于100个对象,R树没有多大意义,因为它可能只包含一个叶子。为了获得良好的性能,R树需要良好的扇出。 k-d-tree总是有扇出2;他们是二叉树。在100k物体上,k-d树将非常深。假设您的扇出为100(对于动态r树,则每页最多允许200个对象),您可以在3级树中存储100万个点。

我使用了ELKI R * -tree,它真的很快。但它不是商业友好的,除非你获得不同的许可证:它是AGPL-3许可的,这是一个copyleft许可证。

此外,API不是为独立使用而设计的。如果你想使用它们,最好的方法是使用完整的ELKI框架,而不是试图撕掉R * -tree。

如果您的数据是低维(例如,3维)并且具有有限界限,请不要低估简单的基于网格的方法的性能。特别是对于内存中的操作。在许多情况下,我甚至不会使用八叉树,而只是为我的用例定义最佳网格,然后使用对象列表实现它。按每个网格单元格中的一个坐标进行排序,以进一步提高性能。

答案 1 :(得分:1)

如果您想频繁添加/删除/更新数据点,您可能需要查看PH树。这是开源Java版本:www.phtree.org

它的工作方式有点像四叉树,但使用二进制超立方体和前缀共享效率更高。

它具有出色的更新性能(无需重新平衡)并且具有极高的内存效率。对于较大的数据集,它可以更好地工作,但对于2维或3维,100K应该没问题。