【发布时间】:2014-06-29 05:44:41
【问题描述】:
我有一个L 点列表(x, y) 和通常的欧几里得距离度量
如何在此列表中找到两点的最大距离?或者,更正式地说:我如何找到
简单的方法
解决这个问题最简单的方法似乎是尝试一切:
def find_max_dist(L):
max_dist = d(L[0], L[1])
for i in range(0, len(L)-1):
for j in range(i+1, len(L):
max_dist = max(d(L[i], L[j]), max_dist)
return max_dist
为了使计算更快,我可以在循环中使用平方距离并在最后返回根。
这种方法的运行时间复杂度为,其中n 是列表L 的长度。 (以及恒定的空间复杂度)。
凸包
显然,没有任何算法比 O(n) 更快,因为我们必须对列表中的每个元素至少查看一次。
凸包元素之间的距离最大。但是很容易证明凸包的计算至少在O(n log n) 和Graham's scan 似乎做到了。但是在找到复杂的船体之后,我仍然必须获得最大距离。所以我最终会得到
def find_max_dist_graham_triv(L):
H = Graham_scan(L)
return find_max_dist(L)
现在,这是我不确定的一点。我认为可以这样改进:
def find_max_dist_graham_c1(L):
H = Graham_scan(L) # Get ordered list of convex hull points
max_dist = d(L[0], L[1])
for i in range(0, len(L)-1):
loop_max_dist = 0
for j in range(i+1, len(L):
curr_dist = d(L[i], L[j])
if curr_dist < loop_max_dist:
break
loop_max_dist = curr_dist
max_dist = max(loop_max_dist, max_dist)
return max_dist
这个想法是,当你取一个凸包的一个点并从它的相邻点开始时,对角线会不断增加,达到最大值,然后不断减小。不过,我不确定这是否属实。
直观地说,我会继续改进算法:一旦第一个内循环完成,我们就找到了该循环的“最长对角线”。这条对角线将所有其他船体点分隔成两个分离的集合。每条较长的对角线都必须由这两个集合中的点组成(对吗?):
def find_max_dist_graham_c1(L):
H = Graham_scan(L) # Get ordered list of convex hull points
max_dist = d(L[0], L[1]) # Get a fist idea what the longest distance might be
i = 0
p1 = L[i] # Grab a random point
loop_max_dist = 0
for j in range(1, len(L):
curr_dist = d(L[i], L[j])
if curr_dist < loop_max_dist:
break
loop_max_dist = curr_dist
max_dist = max(loop_max_dist, max_dist)
# Every diagonal that is longer than the best one found with L[0]
# has to have points in both of the following two sets (correct?):
# [1...j] and [j+1...len(L)]
# Try to find a neighboring diagonal that is longer.
change = True
while change:
change = False
if d(L[i-1], L[j+1]) > max_dist:
max_dist = d(L[i-1], L[j+1])
i -= 1
j += 1
change = True
elif d(L[i+1], L[j-1]) > max_dist:
max_dist = d(L[i+1], L[j-1])
i += 1
j -= 1
change = True
return max_dist
凸包上的每个点 P 在凸包上都有一个点 Q,使得 PQ 是包括 P 在内的最长对角线。但是 P 也是 Q 的最长对角线的“端点”吗?
我真的不确定这个算法是否正确。它会在 O(n log n) 中。
我想这个问题分析得很好,所以有人可以留下一些笔记吗?
虽然我有很多子问题,但主要问题是:
找到点列表中点的最大距离的有效方法是什么?
【问题讨论】:
-
你想找到相距最远的2个点吗?
-
@Amir:不,我想得到彼此最远的2个点的距离。
-
两个固定点之间的距离如何变化?
-
我认为你是在正确的轨道上。您可以使用二分搜索改进第二部分。对于凸包上的每个点,搜索距离它最大的点。即下一个点的距离和上一个点的距离小于当前点。
-
@Amir:两个固定点之间的距离不变。为什么要问?