二維空間最近點對問題 python
阿新 • • 發佈:2018-12-31
給定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()