查找列表中距离指定点最近的点对

172 阅读1分钟

给定一个点集合 s 和一个点 coord,需要从 s 中找到与 coord 最近的点对。

例如,对于 s 中的点集:

[(35.9879845760485, -4.74093235801354), (35.9888687992442, -4.72708076713794),(35.9889733432982, -4.72758983150694), (35.9915751019521, -4.72772881198689), (35.9935223025608, -4.72814213543564), (35.9941433944962, -4.72867416528065), (35.9946670576458, -4.72915181755908), (35.995946587966, -4.73005565674077), (35.9961479762973, -4.7306870912609), (35.9963563641681, -4.7313535758683), (35.9968685892892, -4.73182757975504), (35.9976738530666, -4.73194429867996) ]

coord 点:

(35.9945570576458, -4.73110757975504)

目标是找到 s 中与 coord 点距离最近的点对。

解决方案:

方法一:使用距离函数和内置的 min() 函数

  1. 定义一个距离函数 dist(),用于计算两个点之间的距离:
def dist(s, d):
    return (s[0] - d[0]) ** 2 + (s[1] - d[1]) ** 2
  1. 使用 min() 函数找到距离 coord 最近的点:
min_dist = float('inf')
closest_pair = None

for point in s:
    distance = dist(point, coord)
    if distance < min_dist:
        min_dist = distance
        closest_pair = point

方法二:使用 scipy.spatial.cKDTree

  1. 导入 scipy.spatial.cKDTree 模块:
from scipy.spatial import cKDTree
  1. 将点集合 s 转换为 numpy 数组:
data = numpy.array(s)
  1. 创建一个 cKDTree 对象:
tree = cKDTree(data)
  1. 查询 coord 点附近的最近点:
dists, indexes = tree.query(numpy.array([coord]), k=3)
  1. 选择距离最小的点对:
closest_pair = data[indexes[0]]

方法三:使用线性搜索

  1. 定义一个距离函数 dist_sq(),用于计算两个点之间的距离平方(避免开方计算提高效率):
def dist_sq(a, b):
  return (a[0] - b[0])**2 + (a[1] - b[1])**2
  1. 使用 min() 函数找到距离 coord 最近的点:
closest_pair = min(s, key=lambda p: dist_sq(coord, p))

代码例子:

# 方法一:使用距离函数和内置的 min() 函数

def dist(s, d):
    return (s[0] - d[0]) ** 2 + (s[1] - d[1]) ** 2

min_dist = float('inf')
closest_pair = None

s = [(35.9879845760485, -4.74093235801354), (35.9888687992442, -4.72708076713794),
(35.9889733432982, -4.72758983150694), (35.9915751019521, -4.72772881198689),
(35.9935223025608, -4.72814213543564), (35.9941433944962, -4.72867416528065),
(35.9946670576458, -4.72915181755908), (35.995946587966, -4.73005565674077),
(35.9961479762973, -4.7306870912609), (35.9963563641681, -4.7313535758683),
(35.9968685892892, -4.73182757975504), (35.9976738530666, -4.73194429867996)]

coord = (35.9945570576458, -4.73110757975504)

for point in s:
    distance = dist(point, coord)
    if distance < min_dist:
        min_dist = distance
        closest_pair = point

print(closest_pair)


# 方法二:使用 scipy.spatial.cKDTree

import numpy
from scipy.spatial import cKDTree

data = numpy.array([(35.9879845760485, -4.74093235801354), (35.9888687992442,
-4.72708076713794), (35.9889733432982, -4.72758983150