分治法最近点对可视化python

import math
from random import uniform
import matplotlib.pyplot as plt
from typing import List, Tuple

hdasc: int = 10
ldasc: float = 1e-5
dapr: int = 30
points: List[Tuple[float,float]] = [(uniform(ldasc, hdasc), uniform(ldasc, hdasc)) for i in range(dapr)]
re: List[Tuple[float,float]] = [(0, 0), (0, 0)]
re1: List[Tuple[float,float]] = [(0, 0), (0, 0)]
t: List[int] = []
t1: List[int] = []
mindis:float = 100.0
def distance(p1: Tuple, p2: Tuple) -> float:
    return (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2
def nextpoint(l: int , r: int ) -> None:
    global mindis,re,t,t1
    m = (l + r) >> 1
    if l == r: return
    if l + 1 == r:
        if  distance(points[l], points[r]) < mindis:
            mindis = distance(points[l], points[r])
            re[0]=points[l]
            re[1]=points[r]
        return
    nextpoint(l, m)
    nextpoint(m, r)
    for i in range(l, m):
        if points[m][0] - points[i][0] <= mindis:
            t.append(i)
    for i in range(m, r+1):
        if points[i][0] - points[m][0] <= mindis:
            t1.append(i)
    if(len(t)>len(t1)):#如果t更长,则遍历t1
        t,t1=t1,t
    for i in t:
        for j in t1:
            if points[j][0] - points[i][0] > mindis:# t,t1内部按横坐标有序,如果|x1-x2|>dis,则不用考虑
                break
            if math.fabs(points[i][1] - points[j][1]) < mindis:
                # for k in range(j, min(j+9,len(t1))):#
                    if distance(points[i], points[j]) < mindis:
                        mindis= distance(points[i], points[j])
                        re[0] = points[i]
                        re[1] = points[j]
                # break
    t.clear()
    t1.clear()
#暴力法求解验证
def viled(l: int ,r: int ) -> int :
    vdis: float=distance(points[l], points[r])
    for i in range(l,r+1):
        for j in range(i+1,r+1):
            if distance(points[i], points[j]) < vdis:
                vdis = distance(points[i], points[j])
                re1[0] = points[i]
                re1[1] = points[j]
    return vdis
points.sort(key=lambda x: x[0])
nextpoint(0, len(points) - 1)
mark = '.'
col = 'red'
plt.scatter([i[0] for i in points], [i[1] for i in points], marker=mark)
plt.scatter([i[0] for i in re],[j[1] for j in re], marker=mark, color=col)
print(re)

print(math.sqrt(mindis))
plt.show()


posted @ 2024-06-14 14:49  CV小能手chh  阅读(10)  评论(0)    收藏  举报  来源