算法设计与分析实践-作业5-最近点对问题

算法设计与分析实践-作业5-最近点对问题

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)。
    在这里插入图片描述
    设S是来自Q,位于分割线2d宽度范围内的垂直带的点的列表。由于Q的特点,因此S是按照y轴坐标升序排列的。我们扫描该列表,当遇到更近的点对时,更新目前为止的最小距离dmin。初始情况下dmin=d,但接下来dmin<=d。设p(x,y)为列表中的点。如果另一个点p‘(x’,y‘)和p点的距离小于dmin,那么在列表S中,p’点一定位于p点后面,并且两点在y轴上的距离一定要小于dmin。在几何上,这也就意味着p‘点一定包含在图(b)中的矩形内。该算法主要原理利用了以下事实:矩形内一般只能够包含少量候选点,因为在矩形另一边(左半边和右半边)内,点与点之间的距离至少为d。

3. 设计

下面是处理该问题时的伪代码:

EfficientClosestPair(P,Q)
//使用分治算法来求解最近点对问题
//输入:数组P中储存了平面上的 n>=3 个点,并且按照这些点的x轴坐标升序排列
//输入:数组Q存储了与P相同的点,只是它是按照这点的y轴坐标升序排列
//输出:最近点对之间的欧几里得距离
if n<=2
	返回两个点之间的距离
elseP 的前 ceil(n/2)个点复制到 P left
	将 Q 的前 ceil(n/2)个点复制到 Q left
	将 P 中余下的 floor(n/2)个点复制到 P right
	将 Q 中余下的 floor(n/2)个点复制到 Q right
	d left = EfficientClosestPair( P left, Q left)
	d right = EfficientClosestPair( P right, Q right)
	d = min{d left, d right}
	m = P[ceil(n/2)-1].x
	将 Q 中所有 |x-m|<d 的点复制到数组 S[0...num-1]
	dminsq = d^2
	for i=0 to num-2 do:
		k = i+1
		while k<=num-1 and (S[k].y-S[i].y)*(S[k].y-S[i].y) <dminsq
			dminsq = min((S[k].x - S[i].x)^2+(S[k].y - S[i].y)^2,dminsq)
			k = k+1
return sqrt(dminsq)
	

4.分析:

在这里插入图片描述
在这里插入图片描述

5. 源码

https://github.com/Ericjin1022/-suanfa

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值