一个二维平面上有n个点,求出最近的两个点之间的距离
该问题最简单粗暴的方法便每两个点之间求一次距离的算法,该方法时间复杂度为o(n^2),肯定难以满足需要。
针对这种问题,分而治之的思想可以很好的用到。
针对一个平面,首先分成两个部分,可以用python的sort函数根据x坐标排序,找到中间点,由该点x坐标切分成两个子序列,递归调用。
当切分到只有2个点的时候计算相互距离。接下来,需要把被分割的图像聚合起来,可以通过当前最短距离设置为阈值,把分割线左右最短距离设置为有效区,超过这个区域的点之间距离肯定要大于最短距离。
代码如下:
import math
import random
a=[(500*random.random(), 500*random.random()) for i in range(0,300)] 生成随机点
a.sort()
par=[]
mi=float("inf")
def eudis(x,y):
global par
h=math.sqrt((x[0]-y[0])**2+(x[1]-y[1])**2)
if h<mi:
par=[] 当发现最短距离时保存坐标
par.append(x)
par.append(y)
return h
def combine(l1,l2,alpha):
x=float("inf")
mini=l1[-1][0]-alpha alpha为当前最短距离
maxi=l1[-1][0]+alpha
for i in l1:
if (mini<i[0]<maxi):
for j in l2:
if ((mini<j[0]<maxi)and abs(i[1]-j[1])<alpha):
x=min(x,eudis(i,j))
return x
def divide(a):
global mi 需要设置全局变量,才可以进行修改
if (len(a)==2):
return eudis(a[0],a[1])
if (len(a)<2):
return float("inf")
else:
i=int(len(a)/2)
left = a[0:i]
right = a[i:]
s1=divide(left)
s2=divide(right)
s3=combine(left,right,mi)
s=min(s1,s2,s3)
mi=min(s,mi)
return mi
jieguo=divide(a)
print(jieguo,par)