1
课程名称 《算法分析与设计》 实验日期 年 月 日 至 年 月 日
学生姓名 所在班级 学号
实验名称
实验地点 同组人员
1.问题
在数组P中存储平面上的n>=2个点,并且按照这些点的x轴坐标升序排列,数组Q中存储与P相同的点,只是它按照这些点的y 轴坐标升序排序,得出最近点之间的欧几里得距离。
2.解析
(1)蛮力算法:当2≤n≤3时,问题就可以通过蛮力算法解决。
(2)分治算法:当n>3时,可以利用点集在x轴方向上的中位数m,在该处作一条垂线,将点集分成大小分别为⌈n/2⌉和⌊n/2⌋的两个子集P1和Pr。即使得其中⌈n/2⌉个点位于显得左边或线上,⌊n/2⌋个点位于线的右边或线上。然后就可以通过递归求解子问题P1和Pr来的到最近点点对问题的解。其中d1和dr分别表示在P1和Pr中的最近对距离,并定义d = min{d1,dr}。但请注意,d不一定是所有点对的最小距离,因为距离最近的两个点可能分别位于分界线的两侧。因此,在合并较小子问题的解时,需要检查是否有这样的点。显然,我们可以只关注以分割带为对称的、宽度为2d的垂直带中的点,因为任何其他点对的距离都至少为d。
3.设计
EfficientClosestPair(P,Q){
if n<=3
返回蛮力算法求得的最小距离;
else
将P的前⌈n/2⌉个点复制到Pl;
将Q的前⌈n/2⌉个点复制到Q1;
将P中余下的⌊n/2⌋个点复制到Pr;
将Q中余下的⌊n/2⌋个点复制到Qr;
dl<—EfficientClosestPair(Pl,Q1);
dr<—EfficientClosestPair(Pr,Qr);
d<—min{d1,dr};
m<—P[⌈n/2⌉-1].x;
将Q中所有|x-m|<d的点复制到数组s[0…num-1];
dminsq<—d²;
for i=0 to num-2 do
k<—i+1
while k<=num-1 and (s[k].y-s[i].y)² < dminsq
dminsq<—min((s[k].x-s[i].x)²+(s[k].y-s[i].y)²,dminsq);
k<—k+1;
return sqrt(dminsq);
4.分析
[算法复杂度推导]
时间复杂度:O(n log n)
5.源码
[github源码地址]
https://github.com/Wanghaonan520/algorithm