Algorithm 直线上给定点的最短距离对?
有人能提出一种算法来找出未排序的共线点的最短距离对吗Algorithm 直线上给定点的最短距离对?,algorithm,computational-geometry,closest-points,Algorithm,Computational Geometry,Closest Points,有人能提出一种算法来找出未排序的共线点的最短距离对吗 我有一个解决方案,它在O(nlogn)中实现这一点,只需执行并应用于行。但是,这能更有效地完成吗?我将针对一个有限范围内的数字列表提出一个解决方案 如果所有的数字都在[a,b]范围内,其中O(b-a)
我有一个解决方案,它在O(nlogn)中实现这一点,只需执行并应用于行。但是,这能更有效地完成吗?我将针对一个有限范围内的数字列表提出一个解决方案 如果所有的数字都在[a,b]范围内,其中O(b-a)
这样,您可以找到最小距离,并通过新数组中的索引获得实际值。恐怕您必须对点进行排序,这至少需要O(n*log(n))时间(除非您可以使用桶排序),因此,我怀疑您是否能找到更快的算法。请注意,通过执行旋转变换,始终可以将2D情况减少为1D情况 不幸的是,在一般情况下,我不认为你能比O(nlogn)做得更好。您最好的选择是对它们进行排序,然后遍历列表。这是平面中最近点对的预期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
def桶(点、桶大小):
返回int(点[0]/buck\u size,int(点[1]/buck\u size)
def插入点(网格、点、buck_大小):
桶=桶(点、桶大小)
网格[buck_size]。追加(点)
def再灰化(点数、限制、buck_大小):
grid=collections.defaultdict(列表)
对于点中的第一个极限点:
插入点(网格、点、buck_大小)
回流栅
#如果点距离网格中任何点的距离小于buck_大小,则返回新距离,
#否则返回inf
def探头(网格、点、buck_尺寸):
原始铲斗=铲斗(点)
对于[-1,0,1]中的delta_x:
对于[-1,0,1]中的增量y:
下一个存储桶=(原始存储桶[0]+delta\u x,原始存储桶[1]+delta\u y)
对于网格中的cand_点[下一个桶]:
#任何单元格中最多有2个点,否则我们将重新刷新
#制造更小的细胞。
如果距离(烛光点、点)
每个邻居候选搜索都是O(1),只需进行一些哈希运算。
该算法需要进行O(log(n))重散列,但每一次都需要与i成比例的时间。需要重新灰化的概率为2/i(=该特定点是目前为止最接近的一对的概率是多少?),即该点在检查i点后位于最近的一对中的概率。因此,预期成本为
总和i=2^n概率[第i步再灰化]*成本(第i步再灰化)+O(1)=
和i=2^n2/i*i+O(1)=
和i=2^n2+O(1)=
O(n)如果(a,b)=(0,1)并且点是0.2和0.3怎么办?这个列表不能保证是整数。很好!但只有当你得到整数时它才起作用。。真的不适合我的情况!!Thanx,兄弟!结果表明,O(nlogn)是最有效的时间复杂度。。顺便说一句,我是这么建议的。谢谢大家的帮助!!!散列,不排序,你可以很容易地击败O(n log n)。排序是足够的,因为没有必要。如果您想找到精确的重复项(而不是接近重复项),您可以使用精确哈希并非常简单地得到一个O(n)算法。你仍然可以玩几何把戏,得到最近对问题的O(n)。我们不想要精确的重复,而是最近点。你的算法方案是什么,适用于O(n)?请你编辑算法,使其更清晰?我被困在第二行(未定义的变量a_1,a_2)。我真的把它充实了起来。但是我仍然没有测试代码。