1.问题
要求在一个包含n个点的集合中,找出距离最近的两个点。
2.解析
1、划分子问题:
将点化为相等的两份,先将点按照横坐标的大小进行排序,然后求出中间值,将其分为两部分。
2、求解子问题:
递归的对两个子问题进行求解:
①先求出左半部分的最短距离(第一对点)
②再求出右半部分的最短距离(第二对点)
③求得中间部分的最短距离(第三对点)
3、
比较三个值中最小的一个,将其返回。
4、第三对点的求解:
先求得第一对点和第二对点,得出两者最小值d。
若在PL中存在一个点s,则PR 中需要计算距离点的y轴坐标一定位于区间[s.y-d, s.y+d]之间,即这样的点一定落在一个d×2d的矩形区域内。设两个点同时存在于一块小区域内,此时最远点距为√((d/2)2+(2d/3)2) =√ 25d2/36 < d2,这与d的定义(S1和S2中任意点对之间的距离小于或等于d)不符,即点s所需要计算点最多有6个,即该步骤可在线性时间内完成。
3.设计
EficientClosestPair(P, Q)
if n<=3
返回由蛮力算法求出的最小距离
else
将P的前[n/2]个点复制到Pl
将Q的前[n/2]个点复制到Ql
将P中余下的[n/2」个点复制到Pr
将Q中余下的[n/2]个点复制到Qr
dl←-EfficientClosestPair(Pl,Ql)
dr←-EfficientClosestPair(Pr,Qr)
D←-min{dl,dr}
m←-P[[n/2]-1].x
将Q中所有|x-m|<d的点复制到数组S[0..num-1]
dminsg←-d
for i←-0 to num-2 do
k←-i+1
while k<=num-1 and (S[k].y-S[i].y)^2 < dminsg
dminsq←-min((S[k].x-S[j].x)^2+(S[k].y-S[j].y)^2,dminsg)
k←-k+1
return sqrt(dminsg)
4.分析
当求a[0…n-1]中n个点的最近点时,设执行时间为T(n),求左右部分中最近点对的时间为T(n/2),求中间部分的时间为O(n),则:
T(n)=O(1) 当n<4
T(n)=2T(n/2)+O(n) 其他情况
从而推出算法的时间复杂度为O(nlog2n)。