![]()
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()