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

1. 问题

P为笛卡尔平面上n>1个点构成的集合,求最近的两个点的距离(n=2k)

2. 解析

(1) 当2<=n<=3时,用蛮力算法求出最小距离。
(2) 当 n>3时,利用点集在x轴方向上的中位数m,在该处作一条垂线,将点集分成大小分别为[n/2]和[n/2]的两个子集Pl和Pr。即使得其中[n/2]个点位于线的左边或线上,[n/2]个位于线的右边或线上。然后就可以通过递归求解子问题Pl和Pr来得到最近点对问题的解。其中dl和dr分别表示在Pl和Pr中的最近对距离,并定义d=min{dl,dr}。
d不一定是所有点对的最小距离,因为距离最近的两个点可能分别位于分界线的两侧。因此,在合并较小子问题的解时,需要检查是否存在这样的点。我们可以只关注以分隔带为对称的、宽度为2d的垂直带中的点,因为任何其他点对的距离都至少为d。
在这里插入图片描述
设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’一定包含在一个矩形中。
在这里插入图片描述

3.设计

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

4.分析

假设n是2的幂
算法运行时间的递归式为:T(n)=2T(n/2)+f(n)
因此算法时间复杂度为O(nlogn)。

5.源码

https://github.com/samfsrhv920/algorithm-analysis

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值