最近点对问题

该博客介绍了如何在笛卡尔平面上找到最近的一对点,通过数据预处理和分治策略优化算法,将问题复杂度从O(n^2)降低到O(nlog2n)。首先对点按x轴排序,然后利用中位数分割点集,递归解决子问题,并检查分割线两侧的点以找到可能的最近点对。最后,通过核心伪代码展示了算法实现。
摘要由CSDN通过智能技术生成

1.问题
在一个笛卡尔平面上有若干个点,找出最近的一对点。
2.解析
数据预处理:令P为笛卡尔平面上n>1个点构成的集合,假设集合中的每个都不一样,我们还假设这些点是按照x轴坐标升序排列的。(如果不是这样,可以事先用类似合并排序这样的高效算法对其进行排序。)为了更加方便,我们还可以按照点的y轴坐标在另一个列表中进行升序排列。
问题分类讨论:
当点的数量n满足:n=2时,两点之间的距离就可以直接得出。
当点的数量n满足:n>=3时,我们可以利用点集在x轴方向上的中位数m,在该处作一条垂线,将点集分成大小分别为ceil(n/2)和floor(n/2)的两个子集Pleft和Pright。即使得其中ceil(n/2)个点位于线的左边或线上,floor(n/2)个点位于线的右边或线上。然后就可以通过递归求解子问题Pleft和Pright来得到最近点对问题的解。
注意点,以上分区域比较所得的d不一定是所有点对的最小距离,因为距离最近的两个点可能分别位于分界线的两侧。因此,在合并较小子问题的解时,需要检查是否存在这样的点。显然,我们可以只关注以分隔带为对称的、宽度为2d的垂直带中的点,因为任何其他的点对的距离都至少为d(见图a)。
3.设计
[核心伪代码]
Pair§{
if n<=3
蛮力算法求得的最小距离(距离公式)
Else
分成左右两段
将S的前⌈n/2⌉个点复制到S, 将S中余下的⌊n/2⌋个点复制到S2;
S1=Pair(lf)
S2=Pair(rt)
m=S[⌈n/2⌉-1].x //求分割线的值
将S中所有|x-m|<d的点复制到数组S[]
dmin=d2
for i=0 to num-2
k=i+1
while k<=num-1 and (s[k].y-s[i].y)2 < dmin
dmin=min((s[k].x-s[i].x)2+(s[k].y-s[i].y)2,dminsq)
k++
end if
return sqrt(dmin)

}
4.分析
[算法复杂度推导]
蛮力: O(n^2)
分治: O(nlog2n)
在这里插入图片描述
5.源码
https://github.com/zbadbx/suanfa/blob/main/%E6%9C%80%E8%BF%91%E7%82%B9%E5%AF%B9%E9%97%AE%E9%A2%98

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值