最短距离对与线上给出的点数?

时间:2011-08-09 15:58:21

标签: algorithm computational-geometry closest-points

有人可以建议算法找出最短距离对未分类的共线点吗?

我有一个解决方案,只需执行closest pair of points in 2D并应用到该行,即可在O(nlogn)中执行此操作。但是,这可以更有效地完成吗?

4 个答案:

答案 0 :(得分:3)

我担心你必须对这些点进行排序,这至少需要O(n * log(n))时间(除非你可以使用桶排序),所以我怀疑你找到了更快的算法。

答案 1 :(得分:2)

请注意,您始终可以通过执行旋转变换将2D大小写缩小为1D大小写。

不幸的是,在一般情况下,我认为你不能比O(nlogn)做得更好。您最好的选择是对它们进行排序,然后遍历列表。

答案 2 :(得分:1)

这是平面中最近点对的预期O(n)时间算法 它来自Kleinberg和Tardos的算法设计书。

这是一个类似Python的伪代码

def Bucket(point, buck_size):
  return int(point[0] / buck_size, int(point[1] / buck_size)

def InsertPoint(grid, point, buck_size):
  bucket = Bucket(point, buck_size)
  grid[buck_size].append(point)

def Rehash(points, limit, buck_size):
  grid = collections.defaultdict(list)
  for first limit point in points:
    InsertPoint(grid, point, buck_size)
  return grid

# return new distance if point is closer than buck_size to any point in grid,
# otherwise return inf
def Probe(grid, point, buck_size):
  orig_bucket = Bucket(point)
  for delta_x in [-1, 0, 1]:
    for delta_y in [-1, 0, 1]:
      next_bucket = (orig_bucket[0] + delta_x, orig_bucket[1] + delta_y)
      for cand_point in grid[next_bucket]:  
        # there at most 2 points in any cell, otherwise we rehash 
        # and make smaller cells.
        if distance(cand_point, point) < buck_size):
          return distance(cand_point, point)
  return inf

def ClosestPair(points):
   random_shuffle(points)
   min_dist = distance(points[0], points[1])
   grid = Rehash(points, 2, min_dist)
   for i = 3 to n
     new_dist = Probe(points, i, grid)
     if new_dist != inf:
        # The key to the algorithm is this happens rarely when i is close to n,
        # and it's cheap when i is close to 0.
        grid = Rehash(points, i, new_dist)
        min_dist = new_dist
     else:
        InsertPoint(point, grid, new_dist)
   return min_dist

每个邻居候选搜索都是O(1),用几个哈希完成。 期望该算法进行O(log(n))重新哈希,但每个都需要与i成比例的时间。需要重新散列的概率是2 / i(==到目前为止,这个特定点是最接近的对的几率是多少?),这个点在检查i点后在最近对中的概率。因此,预期成本是

sum_i = 2 ^ n Prob [步骤i中的Rehash] *成本(在i处重新散列)+ O(1)=

sum_i = 2 ^ n 2 / i * i + O(1)=

sum_i = 2 ^ n 2 + O(1)=

O(n)的

答案 3 :(得分:0)

我只是建议一个解决方案,在这种情况下,你有一个有限范围内的数字列表。

如果所有数字都在[a,b]范围内,其中O(b-a)< O(nlog(n))你可以在O(max(b-a,n))中完成。

创建一个大小为b-a的数组。您可以将其全部启动为0(在O(1)中有一个算法可以执行此操作)

查看您的列表,并为每个值x,在单元格中放置“1”x-a。

然后检查新阵列,并计算具有值的单元格之间的距离。

通过这种方式,您可以找到最小距离,并通过新数组中的索引获取实际值。