我正在尝试找到适合特定问题的空间索引结构:使用联合查找数据结构,我想连接\关联彼此在一定范围内的点。 我有很多要点,我正在尝试通过使用更好的空间索引来优化现有解决方案。
现在,我正在使用一个简单的2D网格索引我的点图的每个宽度[阈值距离]正方形,然后通过搜索网格中相邻正方形中的点来寻找潜在的并集。
然后我计算到相邻像元组合的平方欧几里得距离,并将其与平方阈值进行比较,然后使用联合查找结构(使用路径压缩等进行优化)来构建点组。
以下是该方法的一些说明。黑色的单个点实际上代表了属于网格单元的一组点,而向外的彩色箭头则代表了与外部点的实际距离比较。
(我还在检查属于相同单元格的潜在连接点)。
通过使用此模式,我确保通过使用适当的“邻居单元”模式不进行两次距离比较,该模式在迭代网格单元时不会与已测试的东西重叠。
问题是:这种方法甚至还不够快,我正在尝试用可能更快的方法代替“空间网格索引”方法。
我已经将四叉树作为解决此问题的合适空间索引,但我认为不适合解决该问题(我看不出对特定单元格执行重复“邻居”检查的任何方式)有效地使用四叉树),但也许我错了。
因此,我正在寻找一种更好的算法\数据结构来有效地索引我的点并查询它们的接近度。
谢谢。
答案 0 :(得分:3)
我有一些评论:
1)我认为您的问题等同于“空间连接”。空间连接采用两组几何,例如一组矩形的 R 和一组点的 P ,并为每个矩形找到该矩形中的所有点。在您的情况下, R 是每个点周围的矩形(边长= 2 *最大距离),而点集是 P 。搜索空间连接可能会为您提供一些有用的参考。
2)您可能想看看空间填充曲线。空间填充曲线为一组空间实体(点)创建线性顺序,其特性是,线性顺序中的闭合点通常在空间中也闭合(反之亦然)。这在开发算法时可能很有用。
3)看一下OpenVDB。 OpenVDB具有高度优化的空间索引结构,可以遍历“体素”细胞及其相邻细胞。
4)看一下PH-Tree(免责声明:这是我自己的项目)。 PH树有点像四叉树,但是使用低级位操作来优化导航。它也是Z顺序/ Morten顺序的(请参见上面的空间填充曲线)。您可以为每个点创建一个窗口查询,该查询返回该矩形内的所有点。据我所知,PH-树是此类操作最快的索引结构,尤其是在矩形中通常只有9个点的情况下。如果您对代码感兴趣,则V13实现可能是最快的,但是V16应该更容易理解和修改。 我在较旧的台式机上进行了尝试,使用大约1,000,000个点,每秒可以执行大约200,000个窗口查询,因此,大约需要5秒钟才能找到每个点的所有邻居。
如果您使用的是Java,我的spatial index collection也可能会有用。
答案 1 :(得分:1)
对此的一种标准方法是“ s weep and prune”算法。通过X坐标对所有点进行排序,然后遍历它们。这样做时,请保持点的最低索引位于当前点的阈值距离(以X为单位)之内。该范围内的点可以合并。然后,您可以按Y进行相同的排序。然后,您只需检查X和Y扫描中出现的那些对的欧几里得距离即可。
请注意,如果有很多附近的点“桥接”它们,则使用当前的联合查找方法,最终可以得到彼此相距很远的联合点。因此,您的基本方法-根据接近度合并点组-会引起任意数量的距离误差,而不仅仅是阈值距离。