Skip to content

最近点对

问题描述

给定平面上 m 个点的集合 S,找其中的一对点使得在 n 个点组成的所有点对中,该点对间的距离最小。

问题分析

简单情形:一维数轴

为了使问题易于理解和分析,先来考虑一维的情形。此时 S 中的 n 个点退化为 x 轴上的 n 个实数 x1,x2,,xn。最接近点对即为这 n 个实数中相差最小的 2 个实数。

假设用 x 轴上某个点 mS 划分为小于 m 的子集 S1 和大于 m 的子集 S2。基于平衡子问题的思想,用 S 中各点坐标的中位数来作分割点。在 S1 中找出其最近点对 {p1,p2}(p1>p2),在 S2 中找出其最近点对 {q1,q2}(q1<q2)。于是最短距离分别为

dS1=|p1p2|dS2=|q1q2|

递归地,S 中的最近点对要么是 {p1,p2},要么是 {q1,q2},要么是某个点对 {p3,q3},其中 p3S1q3S2。从而用线性时间就可以将 S1 的解和 S2 的解合并成为 S 的解。

d=min(dS1,dS2,q3p3)

复杂情形:二维平面

选取一垂直线 l:x=m 来作为分割直线。其中 mS 中各点 x 坐标的中位数。由此将 S 分割为 S1S2 两个半平面。

递归地在 S1S2 上找出其最小距离 d1d2 并设 d=min(d1,d2)S 中的最接近点对要么是 d,要么是某个 {p,q},其中 pS1qS2。如图所示:

对于点 pP1,需要考察 P2 中的各个点和点 p 之间的距离是否小于 d。显然 P2 中这样点的 y 轴坐标一定位于区间 [yd,y+d] 之间,而且,这样的点不会超过 6 个。

快速检查 6 个点的方法

  • P1P2 中所有 S 中点按其 y 坐标排好序(预处理)。
  • P1 中所有点,对排好序的点列作一次扫描。
  • P1 中每一点最多只要检查 P2 中排好序的相继 6 个点。

算法分析

一维简单情形和二维情形的时间复杂度均为

T(n)=2T(n2)+O(n)=O(nlogn)
最近更新