一、问题描述

对于平面上的一些点对:p1, p2, …,pn, 找出两个点,使得这两个点之间的距离最小;
解题思路:

  1. 首先对所有的点按照x坐标排序, 然后按x坐标在pivot处将点集二分为坐标点集S1和右边点集S2;
  2. 先递归求得左边点集的最小距离min_left, 然后递归求得右边点集的最小距离min_right; 比较左右点集的最小距离min = min(min_left, min_right);
  3. 此外, 靠近pivot左右min的区域(pivot-min, pivot+min)的区域,存在点对距离小于min,并且一个点在pivot左侧, 一个点在pivot右侧;
    最近点问题(分治算法)

二、优化第三步骤

对于第三步骤中, 求解(pivot-min, pivot+min)区域中的点对, 假设其中有N个点,暴力法计算点对时间是O(n^2), 不可取;
计算区域[pivot-min, pivot+min] 的点对距离可以采用下面优化:
1) 由于点对点两个点一个在左边S_left = [pivot-min, pivot],一个在右边S_right = [pivot, pivot+min],
遍历集合S_left,在S_right中找到一个点,使得其距离小于min;
需要注意, 左边集S_left中的每个点对肯定大于min; 右边集S_right的每个点对肯定大于min;
2) 进一步优化
如果(p, q) 是最近的点对, p在集合S_left 中, q在集合S_right中, 并且q是在下图所示的δ∗2δ长方形上的。需要注意, 在该长方形上,最多只存在6点有效(基于S_right中的每个点对都大于δ, 可以得出最多只有6个点有效;
证明:
最近点问题(分治算法)
3) 综上所述, 可以在合并时候, 通过检测与左边集合p的y坐标相邻的2个或是3个右边集的点(上下); 更进一步, 只求得与p点y坐标上界或是下界的右边集的连续6个点;因此时间复杂度变为O(1), 总的算法的时间复杂度由排序算法所限制;

三、最近点问题代码实现

相关文章: