【分治法】求最近点对问题

本文介绍如何利用分治法解决平面上给定N个点的最近点对问题。通过先对点按x坐标排序,然后不断二分并计算左右两部分及中间地带的最短距离。在中间地带,通过对y坐标排序,仅需检查6个点即可判断是否存在更短距离。递归直至只剩一个或两个点,最终找到最短距离。
摘要由CSDN通过智能技术生成

最近点对

对平面上给定的N个点,给出所有点对的最短距离,即,输入是平面上的N个点,输出是N点中具有最短距离的两点

思路

暴力思路:

使用双重for循环,遍历平面中的所有点对并计算距离,通过比较得到最短距离,时间复杂度为O(N2)

分治法求解:
  • 划分
    • 根据坐标x对平面上的所有点进行排序(x相同则比较y),排序便于随后的划分
    • 在平面上对所有点不断进行二分,当剩余一个点和两个点时可以直接求解,剩余一个点时,距离为∞,剩余两个点时可以直接计算距离。
    • 二分过程中记录左右两部分中的最短距离dist1和dist2
  • 求解:首先,最短距离可能存在于左半部分、右半部分和中间部分,其中左半部分和右半部分可以在递归过程中求出,中间部分则还需计算求解,求解方法:取左右两部分的最短距离记为 δ \delta δ,划分一块“中间地带”,距离中位线 的距离为 δ \delta δ,此时对中间地带的所有点按y坐标进行排序,比较6个点即可判断出中间地带是否存在最短距离
    在这里插入图片描述
    一些思考
    • 为什么只有在2 δ \delta δ* δ \delta δ区域(黑色方框)才是合理范围:首先中间地带的点对距离要小于 δ \delta δ,即左右两部分的最短距离才是有效的,而方框区域内,沿y轴方向的长度为 δ \delta δ,因此在这个范围内的点,才能小于左右两部分求得的最短距离
    • 为什么需要沿y轴排序:根据上一个问题中,沿y轴方向找出最短距离,因此通过排序的贪心策略更容易实现
    • 为什么只用遍历当前点之后的6个点:经过当前点,作一个2 δ \delta δ* δ \delta δ的矩形区域,只有位于矩形四个顶点和矩形与中位线交点上两个点才能满足距离小于 δ \delta δ
      在这里插入图片描述
  • 合并:由于找的是最短距离,无需合并操作

递归体:对平面上的点进行划分,求解并比较中间地带的最短距离和左右两部分最短距离的大小,求出该题的最近点对
递归出口:当剩余一个点和两个点时,可直接计算并返回

代码

暴力
//暴力
void exhaustion(){
   
    for(int i = 0; i < n; ++i){
   
        for(int j = i + 1; j < n; ++j){
   
            double temp = getDist(nodes[i], nodes[j]);
            if(temp < ans){
   
                ans 
  • 15
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值