将点集分组到最近的对

时间:2015-05-27 17:07:22

标签: algorithm computational-geometry nearest-neighbor

我需要一个针对以下问题的算法:

我在平面上给出了一组2D点P = {(x_1,y_1),(x_2,y_2),...,(x_n,y_n)}。我需要以下列方式成对分组:

  1. 在P中找到两个最接近的点(x_a,y_a)和(x_b,y_b)。
  2. 添加对<(x_a,y_a),(x_b,y_b)>到结果集R。
  3. 删除<(x_a,y_a),(x_b,y_b)>来自P.
  4. 如果初始设置P不为空,请转到第一步。
  5. 返回对R的集合。
  6. 该朴素算法为O(n ^ 3),使用更快的算法搜索最近邻居,可以将其改进为O(n ^ 2 logn)。可以做得更好吗?

    如果这些点不在欧几里德空间怎么办?

    一个例子(结果组用红色圆圈圈出):

    enter image description here

4 个答案:

答案 0 :(得分:5)

将所有点放入http://en.wikipedia.org/wiki/R-tree(时间Object),然后为每个点计算到最近邻居的距离。将点和初始距离放入优先级队列。初始化一组空的删除点和一组空的对。然后执行以下伪代码:

O(n log(n))

最慢的部分是最近邻搜索。 R树不保证那些最近邻居搜索将是while priority_queue is not empty: (distance, point) = priority_queue.get(); if point in removed_set: continue neighbor = rtree.find_nearest_neighbor(point) if distance < distance_between(point, neighbor): # The previous neighbor was removed, find the next. priority_queue.add((distance_between(point, neighbor), point) else: # This is the closest pair. found_pairs.add(point, neighbor) removed_set.add(point) removed_set.add(neighbor) rtree.remove(point) rtree.remove(neighbor) 。但他们往往是。此外,您不是保证您将为每个点执行O(log(n))个邻居搜索。但通常你会。所以平均表现应该是O(1)。 (我可能错过了一个对数因子。)

答案 1 :(得分:2)

我想这个问题需要一个动态的Voronoi图。

当已知点集的Voronoi图时,可以在线性时间内找到最近邻对。

然后删除这两个点可以在线性或次线性时间内完成(我没有找到准确的信息)。

所以全球范围内你可以期待一个O(N²)解决方案。

答案 2 :(得分:1)

如果你的距离是任意的,你不能将你的点嵌入欧几里德空间(和/或空间的维度真的很高),那么基本上没有办法绕至至少一个二次方时间算法,因为在检查所有对之前,你不知道最接近的对是什么。很容易接近这一点,基本上是根据距离对所有对进行排序,然后维护一个布尔查找表,指出列表中的哪些点已经被采集,然后按顺序浏览已排序的对列表并添加你最近邻居的一对积分&#34;如果该对中的两个点都不在获取点的查找表中,然后将该对中的两个点添加到查找表中,如果是这样的话。复杂度O(n ^ 2 log n),带有O(n ^ 2)额外空间。

答案 3 :(得分:1)

你可以找到在O(nlogn)时间内运行的this divide and conquer algorithm最近的一对,你可以重复这n次,你会得到O(n ^ 2 logn),这并不比你得到的好。

然而,您可以利用分而治之算法的递归结构。想想看,如果你移除的那对点位于分区的右侧,那么左侧的一切都会表现相同,没有任何改变,所以你只需要自下而上重做O(logn)合并步骤。但是考虑到第一个新的合并步骤将合并2个元素,第二个合并4个元素然后8个,然后16个,...,n / 4,n / 2,n,所以这些合并步骤的操作总数是O(n),所以你在O(n)时间内得到第二个最接近的对。因此,通过删除先前找到的对来重复此n / 2次,并获得具有O(nlogn)额外空间的总O(n ^ 2)运行时以跟踪递归步骤,这稍微好一些。

但是你可以做得更好,有一个随机数据结构,可以让你在你的点集中进行更新并获得预期的O(logn)查询和更新时间。我对这个特定的数据结构不太熟悉,但您可以在this paper中找到它。这将使你的算法O(nlogn)预期时间,我不确定是否有一个具有相似运行时的确定性版本,但那些往往更麻烦。