最近对问题

1.问题
n个点在公共空间中,求出所有点对的欧几里得距离最小的点对。
2.解析
令P为笛卡儿平面上n>1个点构成的集合,简单起见,假设集合中的每个点都不一样,且这些点按照x轴坐标升序排列,并将这个列表示为Q。
当2<=n<=3时,问题就可以通过蛮力算法求解。当n>3时,可以利用点集在x轴方向上的中位数m,在该处做一条垂线,将点集分成大小分别为n/2(向上取整),n/2(向下取整)的两个子集Pl和Pr。然后就可以通过递归求解子问题Pl和Pr来得到最近对问题的解。其中dl和dr分别表示在Pl和Pr中最近对距离,并定义d=min{dl,dr}
3.设计
核心伪代码,课本P148
(尽量避免在最内层循环中计算平方根)
EfficientClosest Pair(P,Q)//(分治)
//输入 (1)P存n≥2个点,按其x轴坐标升序排序;
(2)Q存和P相同的点,按其y轴坐标升序排序;
//输出:最近点对之间的欧几里得距离;

if n≤3 返回蛮力算法求出dmin;
else
将P的前半部分(n/2)个点复制到P1,Q的前半部分(n/2)个点复制到Q1中;
将P的余下部分(n/2)个点复制到Pr,Q的余下部分(n/2)个点复制到Qr中;

d1←EfficientClosest Pair(P1,Q1)
dr←EfficientClosest Pair(Pr,Qr)
d←min{d1,dr}
m←P[前半部分(n/2)-1].x
将Q中所有绝对值(x-m)<d的点复制到数组S[0…num-1]
dmin=sqrt((y2-y1)(y2-y1)+(x2-x1)(x2-x1))
dminsq←dd
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)<dimsq
dminsq←min((S[k].x-S[i].x)(S[k].x-S[i].x)+(S[k].y-S[i].y)(S[k].y-S[i].y)),dminsq)
k←k+1
return sqrt(dminsq)
3.分析
无论将问题划分成两个规模减半的子问题,还是合并子问题的解,该算法都只需要线性时间,因此,假设n是2的幂,可以得到算法运行时间的递归式:T(n)=2T(n/2)+f(n);

上一篇:AE、PR视频制作遇到的问题


下一篇:CSP-S2020 贪吃蛇(洛谷民间数据)