1. 程式人生 > >二維空間最近點對問題 python

二維空間最近點對問題 python

給定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()