- 请参考教材98页,算法6.6,先来个常规算法,复杂度为n的平方,结合Python的优势,代码整短点,顺便绘制下图形,算法思路简单,不多说了,注意陷阱。
- 上代码了:
#coding=utf-8
import math
import matplotlib.pyplot as plt
def closestpair_simple(X, n):
#对于n个数据点,计算n(n-1)/2个数就可以了
dist = [[distance(X[i], X[j]), i, j] for i in range(len(X)) for j in range(i+1,len(X))]
return min(dist)[0], [min(dist)[1], min(dist)[2]]
def distance(a, b):
return math.sqrt(math.pow(a[0]-b[0], 2)+math.pow(a[1]-b[1], 2))
if __name__ == "__main__":
points = [(2,3), (10, 1), (3, 25), (23,15), (18,3), (8,9), (12,30), (25,30), (9,2),
(13,10), (3,4), (5,6), (22,32), (5,32), (23,9), (19,25), (14,1), (11,25), (26,26),
(12,9), (18,9), (27,13), (32,13)]
print (closestpair_simple(points, len(points)))
#绘制这些点
x = [points[i][0] for i in range(len(points)) ]
y = [points[j][1] for j in range(len(points))]
plt.plot(x, y, 'ro')
plt.plot([2, 3], [3, 4]) #绘制两个点之间的连线,多了的时候可以循环
plt.show()
- 绘制的图形:

- 感兴趣的童鞋可以把点的坐标自己标上,不过没啥用,本身就能看得出来。
- 另外一种是分治算法,里面的难点就是跨界解怎么求?当然了点序列怎么分成子问题,分割也是个麻烦的问题。就比如下面图示这种情况:

- 详细的难点课堂上会讲解,记得预习即可。分治法求解代码贴上先:
import math
def closest(P, n):
X = list(P)
Y = list(P)
X.sort()
Y = sort_y(Y)
return closest_pair(X, Y, n)
def sort_y(Y):
return sorted(Y, key=lambda last:last[-1])
def closest_pair(X, Y, n):
if n <= 3:
return brute_force(X, n)
mid = n / 2
Y_left = []
Y_right = []
for p in Y:
if p in X[:mid]:
Y_left.append(p)
else:
Y_right.append(p)
dis_left = closest_pair(X[:mid], Y_left, mid)
dis_right = closest_pair(X[mid:], Y_right, n-mid)
min_dis = min(dis_left, dis_right)
strip = []
for (x, y) in Y:
if abs(x-X[mid][0]) < min_dis:
strip.append((x, y))
return min(min_dis, strip_closest(strip, min_dis))
def brute_force(X, n):
min_d = distance(X[0], X[1])
for i, (x, y) in enumerate(X):
for j in range(i+1, n):
if distance(X[i], X[j]) < min_d:
min_d = distance(X[i], X[j])
return min_d
def distance(a, b):
return math.sqrt(math.pow((a[0]-b[0]), 2)+math.pow((a[1]-b[1]), 2))
def strip_closest(strip, d):
min_d = d
for i, (x, y) in enumerate(strip):
for j in range(i+1, 6):
if i + j < len(strip):
temdis = distance(strip[i], strip[j])
if temdis < min_d:
min_d = temdis
return min_d
if __name__ == "__main__":
points = [(2,3), (10, 1), (3, 25), (23,15),
(18,3), (8,9), (12,30), (25,30),
(9,2), (13,10), (3,4), (5,6),
(22,32), (5,32), (23,9), (19,25),
(14,1), (11,25), (26,26), (12,9),
(18,9), (27,13), (32,13)]
print (closest(points, len(points)))