最近点对问题python解法

开始复习之前学过的内容,与大家分享下

目标:

INPUT: 平面上的 n 个点

OUTPUT: 欧式距离最近的点对

最原始想法:遍历所有点的集合,具有o(n^2)的时间复杂度

可以使用分治思想进行算法优化.

首先将所有点按照X轴排序(Y轴也可以),之后进行分割为左一半元素,右一半元素,最后左右分别求最近点,最后进行合并,找到左面和右面的点集合里面最小的.

这里的一个trick是找到左右最小距离后,只需要在中间位置使用最小距离约束,如下,左右最小距离是12,只需要考虑中线(-12,12)以内的值就可以,最后递归调用即可


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
    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)


猜你喜欢

转载自blog.csdn.net/a5139515/article/details/78927888