分治法之最近对问题

问题

n个点在二维平面内,求出所有点对的欧几里得距离最小的点对。

解析

在利用分治法思想解决此问题时,首先考虑将最近对问题进行分治,设计其分治策略。将集合S分成两个子集S1和S2,根据平衡子问题原则,每个子集中的点数大致都为n/2。这样分治后,最近点对将会出现三种情况:在S1中,在S2中或者最近点对分别在集合S1和S2中。利用递归分析法分别计算前两种情况,第三种方法另外分析。求解出三类子情况后,再合并三类情况,比较分析后输出三者中最小的距离。
在第三种情况中,包含两个点分别在中线的两端,已知前两种情况递归出最小距离为d,所以需要在[mid-d,mid+d]的区间内找出最小距离,与d比较,但是当出现特殊情况,如在该范围内出现的点数较多,该算法的复杂度会趋近于O(n^2),要对这种情况优化为常数级别的复杂度。
若(p,q)是q的最近点对,p在带域左半部分,则q点必在下图所示的d∗2d长方形上,而在该长方形上,最多只能由右边点集的6个点。每个点对之间的距离不小于d。

分治法之最近对问题_第1张图片

设计

1、根据点的y值和x值对S中的点排序。
2、找出中线L将S划分为SL和SR
3、将步骤2递归的应用解决SL和SR的最近点对问题,并令d=min(dL,dR)。
4、将L-d~L+d内的点以y值排序,找出最近6个点找出最短距离为d’。如果d’小于d,令d=d’,最后的d值就是答案。

分析

由公式
在这里插入图片描述
递推法推到时间复杂度O(nlogn)

源码

https://github.com/Geedhayb/Geed/blob/master/minDis.cpp

你可能感兴趣的:(算法分析)