我正在尝试使用分治算法在Python中实现最近点对问题,除了在某些输入情况下出现错误答案外,一切似乎都正常。我的代码如下:
def closestSplitPair(Px,Py,d):
X = Px[len(Px)-1][0]
Sy = [item for item in Py if item[0]>=X-d and item[0]<=X+d]
best,p3,q3 = d,None,None
for i in xrange(0,len(Sy)-2):
for j in xrange(1,min(7,len(Sy)-1-i)):
if dist(Sy[i],Sy[i+j]) < best:
best = (Sy[i],Sy[i+j])
p3,q3 = Sy[i],Sy[i+j]
return (p3,q3,best)
我通过以下递归函数调用了上面的函数:
def closestPair(Px,Py): """Px and Py are input arrays sorted according to
their x and y coordinates respectively"""
if len(Px) <= 3:
return min_dist(Px)
else:
mid = len(Px)/2
Qx = Px[:mid] ### x-sorted left side of P
Qy = Py[:mid] ### y-sorted left side of P
Rx = Px[mid:] ### x-sorted right side of P
Ry = Py[mid:] ### y-sorted right side of P
(p1,q1,d1) = closestPair(Qx,Qy)
(p2,q2,d2) = closestPair(Rx,Ry)
d = min(d1,d2)
(p3,q3,d3) = closestSplitPair(Px,Py,d)
return min((p1,q1,d1),(p2,q2,d2),(p3,q3,d3),key=lambda tup: tup[2])
其中min_dist(P)
是最近点对算法的暴力实现,用于包含3个或更少元素的列表P,并返回一个包含最接近点对及其距离的元组。
如果我的输入为P = [(0,0),(7,6),(2,20),(12,5),(16,16),(5,8),(19,7),(14,22),(8,19),(7,29),(10,11),(1,13)]
,那么输出应为((5,8),(7,6),2.8284271)
,这是正确的输出。但当我的输入为P = [(94, 5), (96, -79), (20, 73), (8, -50), (78, 2), (100, 63), (-14, -69), (99, -8), (-11, -7), (-78, -46)]
时,我得到的输出为((78, 2), (94, 5), 16.278820596099706)
,而正确的输出应该是((94, 5), (99, -8), 13.92838827718412)
P = [ ( random.uniform(-100, 100), random.uniform(-100, 100) ) for k in range(10000) ]
,然后与暴力方法输出进行比较,在某些情况下验证失败。 - maverick93