给定n个二维空间中的点(x1,y1)(x2,y2)...(xn,yn),设计一个寻找两点之间距离最近的点对的算法,并分析算法时间复杂度
暴力求解:
import random
import numpy
import math
import time
import matplotlib.pyplot as plt
import image
# 暴力求解最近点对问题
n = 500
closest_pair = {}
# 存最后结果
buff = {}
minimum = float("inf")
point = [(random.randint(0, 3*n), random.randint(0, 3*n)) for i in range(0, n)]
# 随机生成n个坐标
print(point)
print("\n\n\n")
point.sort()
print(point)
plt.xlim(0, 3*n)
plt.ylim(0, 3*n)
plt.title("Point Pair")
for i in range(len(point)):
plt.plot(point[i][0], point[i][1], 'ro-')
def get_distance(a, b):
global buff
distance = math.sqrt((a[0]-b[0])**2+(a[1]-b[1])**2)
if distance in buff:
buff[distance].append((a, b))
else:
buff[distance] = [(a, b)]
return distance
def judge_minimum(temp):
global minimum
minimum = temp if temp <= minimum else minimum
# 暴力找最小
time_start = time.time()
for i in range(0, n-1):
for j in range(i+1, n):
judge_minimum(get_distance(point[i], point[j]))
closest_pair[minimum] = buff[minimum][:]
# 最后结果存入closest_pair中
time_end = time.time()
print("\n\n\n\nrun_time is :", time_end-time_start)
print("\n\n\n"+"The Closest Pair is:",
closest_pair[minimum], " Distance:", minimum)
for i in range(0, len(closest_pair[minimum])):
plt.plot(closest_pair[minimum][i][0][0],
closest_pair[minimum][i][0][1], "bo-")
plt.plot(closest_pair[minimum][i][1][0],
closest_pair[minimum][i][1][1], "bo-")
plt.show()
分治法求解(较简陋):
import random
import numpy
import math
import time
import matplotlib.pyplot as plt
# 分治法求解最近点对问题
n = 500
minimum = float("inf")
point = [(random.randint(0, 3*n), random.randint(0, 3*n)) for i in range(0, n)]
# 随机生成n个坐标
print(point)
print("\n\n\n")
closest_pair = {}
buff = {}
point.sort()
print(point)
plt.xlim(0, 3*n)
plt.ylim(0, 3*n)
plt.title("Point Pair")
for i in range(len(point)):
plt.plot(point[i][0], point[i][1], 'ro-')
def get_distance(a, b):
# print(a,b)
distance = math.sqrt((a[0]-b[0])**2+(a[1]-b[1])**2)
if distance in buff:
buff[distance].append((a, b))
else:
buff[distance] = [(a, b)]
return distance
def judge_minimum(temp):
global minimum
global buff
if temp not in buff:
return minimum
if minimum < temp:
pass
elif minimum == temp:
for i in range(0, len(buff[temp])):
closest_pair[minimum].append(buff[temp][i])
else:
minimum = temp
closest_pair.clear()
closest_pair[temp] = buff[temp][:]
return minimum
def min_between(point, left, mid, right, minimum):
global buff, closest_pair
for i in range(left, mid):
if abs(point[i][0]-point[mid][0]) <= minimum:
for j in range(mid, right):
if abs(point[i][0]-point[j][0]) <= minimum and abs(point[i][1]-point[j][1]) <= minimum:
get_distance(point[i], point[j])
if len(buff) > 0:
buff = sorted(buff.items(), key=lambda buff: buff[0])
temp = buff[0][0]
buff = dict(buff)
else:
temp = float("inf")
return temp
def divide(point, left, right):
global minimum, buff
# right不包括
if right-left < 2:
return float('inf')
elif right-left == 2:
return get_distance(point[left], point[left+1])
else:
mid = int((left+right)/2)
min_left = divide(point, left, mid)
# print("min_left:",min_left)
minimum = judge_minimum(min_left)
buff.clear()
min_right = divide(point, mid, right)
# print("min_right",min_right)
minimum = judge_minimum(min_right)
buff.clear()
temp = min_between(point, left, mid, right, minimum)
# print("temp",temp)
minimum = judge_minimum(temp)
buff.clear()
return min(min_left, min_right, temp)
time_start = time.time()
divide(point, 0, len(point))
time_end = time.time()
print("\n\n\n\nrun_time is :", time_end-time_start)
print("\n\n\n"+"The Closest Pair is:",
closest_pair[minimum], " Distance:", minimum)
for i in range(0, len(closest_pair[minimum])):
plt.plot(closest_pair[minimum][i][0][0],
closest_pair[minimum][i][0][1], "bo-")
plt.plot(closest_pair[minimum][i][1][0],
closest_pair[minimum][i][1][1], "bo-")
plt.show()