分而治之,二维平面最近点问题

一个二维平面上有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)
     

猜你喜欢

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