老师好,我是刁同学。
- 以先x坐标增序,再y坐标增序对点集S中的点排序
- S点集被垂直线L大约划分成两个子集L是经过x坐标为S[n//2]的垂线
- 递归以上两步,两子集SL和SR的最小间距可分别计算出来lengthl和lengthr
- 组合步骤,把在SL中的点与SR中的点之间最小间距length算出来
import numpy as np
import matplotlib.pyplot as plt
def distance(p,i,j):
h=pow((pow((p[i][0]-p[j][0]),2) +pow((p[i][1] - p[j][1]),2)),1.0/2)
return h
def point():
n=int(input("点集大小:"))
p=[[0,0]]*n
x=[]
y=[]
for i in range (0,n):
p[i]=[float(input("x=")),float(input("y="))]
x.append(p[i][0])
y.append(p[i][1])
return p,x,y
def cp(pair):
global min_i,min_j
min_i =[None,None]
min_j = [None, None]
if len(pair)<=3:
length=1000
for i in range(0,len(pair)):
for j in range(i+1,len(pair)):
if length>=distance(pair,i,j):
length=distance(pair,i,j)
min_i=pair[i]
min_j=pair[j]
else:
mid=len(pair)//2
x0=pair[mid][0]
lengthl=cp(pair[0:mid+1])
MINI=min_i
MINJ=min_j
lengthr=cp(pair[mid+1:])
if lengthl<lengthr:
min_i=MINI
min_j=MINJ
length=min(lengthl,lengthr)
k=0
T=[]
for i in range(0,len(pair)):
if (abs(p[i][0]-x0)<=length):
T.append(p[i])
k+=1
length_=2*length
for i in range(0,k-1):
for j in range(i+1,min(i+7,k)):
if distance(T,i,j)<length_:
length_=distance(T,i,j)
min_i_=T[i]
min_j_=T[j]
if length>length_:
min_i=min_i_
min_j=min_j_
length=min(length,length_)
return length
x=[]
y=[]
p=[[]]
#p=[]
# for _ in range (0,10):
# x.append(np.random.randint(-20,20))
# y.append(np.random.randint(-20,20))
# p.append([x[_],y[_]])
p,x,y=point()
p.sort(key=lambda m:[m[0],m[1]])
print(p)
print(cp(p))
print(min_i)
print(min_j)
plt.figure(figsize=(20,8),dpi=80)
plt.scatter(x,y,s=20,c='b',marker='*')
plt.plot([min_i[0],min_j[0]],[min_i[1],min_j[1]],c='r')
plt.show()
代码的运行结果
***------输入------*** 加载中
点集大小:10
x=7.89 y=6.54
x=3.2 y=9.8
x=7.9 y=3.5
x=-1.4 y=-5.7
x=12.9 y=2
x=2.5 y=4.8
x=-2.3 y=4.4
x=0 y=0.8
x=2.82 y=3.14
x=5.35 y=7
------输出------ 加载中
点集:[[-2.3, 4.4], [-1.4, -5.7], [0.0, 0.8], [2.5, 4.8], [2.82, 3.14], [3.2, 9.8], [5.35, 7.0], [7.89, 6.54], [7.9, 3.5], [12.9, 2.0]]
最近距:1.6905620367203325
PonitA:[2.5, 4.8]
PointB:[2.82, 3.14]
以下是生成50个点时的效果图