`
yzmduncan
  • 浏览: 330300 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

平面最近点对问题详解

阅读更多

    在二维平面上的n个点中,如何快速的找出最近的一对点,就是最近点对问题。

    一种简单的想法是暴力枚举每两个点,记录最小距离,显然,时间复杂度为O(n^2)。

    在这里介绍一种时间复杂度为O(nlognlogn)的算法。其实,这里用到了分治的思想。将所给平面上n个点的集合S分成两个子集S1和S2,每个子集中约有n/2个点。然后在每个子集中递归地求最接近的点对。在这里,一个关键的问题是如何实现分治法中的合并步骤,即由S1和S2的最接近点对,如何求得原集合S中的最接近点对。如果这两个点分别在S1和S2中,问题就变得复杂了。

    为了使问题变得简单,首先考虑一维的情形。此时,S中的n个点退化为x轴上的n个实数x1,x2,...,xn。最接近点对即为这n个实数中相差最小的两个实数。显然可以先将点排好序,然后线性扫描就可以了。但我们为了便于推广到二维的情形,尝试用分治法解决这个问题。

    假设我们用m点将S分为S1和S2两个集合,这样一来,对于所有的p(S1中的点)和q(S2中的点),有p<q。

    递归地在S1和S2上找出其最接近点对{p1,p2}和{q1,q2},并设

d = min{ |p1-p2| , |q1-q2| }

    由此易知,S中最接近点对或者是{p1,p2},或者是{q1,q2},或者是某个{q3,p3},如下图所示。



 

    如果最接近点对是{q3,p3},即|p3-q3|<d,则p3和q3两者与m的距离都不超过d,且在区间(m-d,d]和(d,m+d]各有且仅有一个点。这样,就可以在线性时间内实现合并。

    此时,一维情形下的最近点对时间复杂度为O(nlogn)。

    在二维情形下,类似的,利用分治法,但是难点在于如何实现线性的合并?



 

    由上图可见,形成的宽为2d的带状区间,最多可能有n个点,合并时间最坏情况下为n^2,。但是,P1和P2中的点具有以下稀疏的性质,对于P1中的任意一点,P2中的点必定落在一个d X 2d的矩形中,且最多只需检查六个点(鸽巢原理)。

    这样,先将带状区间的点按y坐标排序,然后线性扫描,这样合并的时间复杂度为O(nlogn),几乎为线性了。

 

    光说不练也不行,经过自己的思考和参考网上的程序,完成了最近点对的程序,并在各OJ上成功AC了。

    POJ3714 ZOJ2107 HDU1007

/**
最近点对问题,时间复杂度为O(n*logn*logn)
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const double INF = 1e20;
const int N = 100005;

struct Point
{
    double x;
    double y;
}point[N];
int n;
int tmpt[N];

bool cmpxy(const Point& a, const Point& b)
{
    if(a.x != b.x)
        return a.x < b.x;
    return a.y < b.y;
}

bool cmpy(const int& a, const int& b)
{
    return point[a].y < point[b].y;
}

double min(double a, double b)
{
    return a < b ? a : b;
}

double dis(int i, int j)
{
    return sqrt((point[i].x-point[j].x)*(point[i].x-point[j].x)
                + (point[i].y-point[j].y)*(point[i].y-point[j].y));
}

double Closest_Pair(int left, int right)
{
    double d = INF;
    if(left==right)
        return d;
    if(left + 1 == right)
        return dis(left, right);
    int mid = (left+right)>>1;
    double d1 = Closest_Pair(left,mid);
    double d2 = Closest_Pair(mid+1,right);
    d = min(d1,d2);
    int i,j,k=0;
    //分离出宽度为d的区间
    for(i = left; i <= right; i++)
    {
        if(fabs(point[mid].x-point[i].x) <= d)
            tmpt[k++] = i;
    }
    sort(tmpt,tmpt+k,cmpy);
    //线性扫描
    for(i = 0; i < k; i++)
    {
        for(j = i+1; j < k && point[tmpt[j]].y-point[tmpt[i]].y<d; j++)
        {
            double d3 = dis(tmpt[i],tmpt[j]);
            if(d > d3)
                d = d3;
        }
    }
    return d;
}


int main()
{
    while(true)
    {
        scanf("%d",&n);
        if(n==0)
            break;
        for(int i = 0; i < n; i++)
            scanf("%lf %lf",&point[i].x,&point[i].y);
        sort(point,point+n,cmpxy);
        printf("%.2lf\n",Closest_Pair(0,n-1)/2);
    }
    return 0;
}

 

 

  • 大小: 5.7 KB
  • 大小: 12.8 KB
2
0
分享到:
评论

相关推荐

    分治法求平面最近点报告

    1. **问题描述**:理解平面最近点问题的具体背景与意义。 2. **算法设计思想**:掌握分治法解决问题的基本思路。 3. **程序设计**:学会使用C++编程语言实现分治法求解平面最近点问题。 4. **复杂性分析**:能够对...

    四参数法平面坐标转换处理工具详解

    【四参数法平面坐标转换处理工具详解】 四参数法是一种常用的平面坐标转换方法,它基于仿射变换理论,用于在两个平面坐标系统之间进行转换。这种方法适用于在同一椭球体下的不同投影坐标之间的转换,比如在高斯-...

    ClosetPair最近点对问题

    《ClosetPair最近点对问题详解》 在计算机科学领域,尤其是在几何算法中,"ClosetPair"(最近点对问题)是一个经典的问题。它的核心是寻找一组给定点集中的两个点,使得它们之间的距离最小。这个问题在各种应用中都...

    java实现最近点问题(带图像).doc

    【标题】:Java 实现最近点问题(带图像) 【描述】:本示例通过分治法解决二维平面上的最近点对问题,程序能够随机生成多个点,并在图形界面上展示这些点以及找到的最近点对之间的连线。同时,控制台会输出最近点...

    最近对问题,分治法与蛮力法

    - 对于最近对问题,我们可以将平面分割成两半,分别计算左半部分和右半部分的最近点对,然后处理跨越这两半之间的点对。 - 时间复杂度为 \(O(n\log n)\),显著优于蛮力法。 **代码片段**: ```cpp double DivPoints...

    平面向量与复数学案,高中数学平面向量与复数课程详解.pptx

    平面向量与复数学案 ...复数有很多实际应用,如解决某些简单的平面几何问题、解决简单的力学问题和其他一些实际问题。 本资源涵盖了平面向量和复数的概念、性质、运算和应用,适合高中学生和数学爱好者学习和参考。

    平面解析几何学案,高中数学平面解析几何课程详解.pptx

    这些知识点构成了平面解析几何的核心,它们是高中生理解和解决问题的基础,也是进一步学习高级数学概念的基石。通过深入理解和熟练运用这些知识,学生可以更好地掌握数学思维,并为未来的学术和职业发展打下坚实基础...

    弹性力学简明教程第四章平面问题的极坐标解答习题详解.docx

    《弹性力学简明教程》第四章主要探讨了平面问题在极坐标系下的解答方法,尤其关注了极坐标下弹性体的平衡微分方程、几何方程和物理方程。在这一章中,通过典型例题讲解了如何解决具体问题。 在例题4-1中,我们考虑...

    结构光光平面标定源码

    - **标定板识别**:代码中可能有对棋盘格或其他特征点的检测和提取函数。 - **结构光解码**:这部分代码会解析结构光在图像中的投影,例如条纹编码的解码算法。 - **投影与图像对应点匹配**:寻找结构光特征点与相机...

    Photoshop平面设计PPT详解

    PS平面设计是用AdobePhotoshop进行平面设计。...图像处理是对已有的位图图像进行编辑加工处理以及运用一些特殊效果,其重点在于对图像的处理加工;图形创作软件是按照自己的构思创意,使用矢量图形等来设计图形。

    弹性力学平面问题有限元程序matlab.rar

    《弹性力学平面问题有限元程序MATLAB实现详解》 在计算力学领域,弹性力学是研究物体在外力作用下如何发生变形以及如何恢复原状的重要理论基础。而在解决复杂形状和结构的问题时,有限元方法(Finite Element ...

    Unity3D 游戏引擎之平面小球重力感应详解

    《Unity3D游戏引擎之平面小球重力感应详解》 Unity3D是一款强大的跨平台游戏开发工具,广泛应用于手机游戏、桌面游戏以及虚拟现实应用的制作。在本教程中,我们将深入探讨如何利用Unity3D实现平面小球的重力感应...

    储油罐的变位识别与罐容标定问题详解。

    标题中的“储油罐的变位识别与罐容标定问题详解”主要涉及的是石油储存设施中的关键技术,包括储油罐的位置变化检测以及确定其容量的方法。这通常涉及到工程测量学、数学建模和计算方法。在实际操作中,储油罐可能会...

    2017_2018学年高中数学第二章点直线平面之间的位置关系2.1空间点直线平面之间的位置关系2.1.1平面优化练习新人教A版必

    6. **正方体的性质**:问题7和问题9探讨了正方体的特殊性质,如对角线的交点、平面的交集等。例如,AC和BD的交点是正方体的中心点O,而平面AB1和A1C1的交集是A1B1。 7. **平面判定**:问题8强调了空间中直线平行和...

    支持向量机详解(SVM)

    这个超平面被称为最大间隔超平面,与之最近的那些样本点被称为支持向量。 为了求解最大间隔超平面,需要通过优化问题来表达。该问题可以转换为一个二次规划问题,并使用拉格朗日乘法进行对偶化,以形成对偶问题。...

    Geogebra中自定义平面坐标系工具的创建和使用

    软件支持创建自定义平面坐标系工具,使得用户可以更直观地探索和理解数学问题。接下来将详细讲解如何在Geogebra中创建和使用自定义平面坐标系工具。 首先需要了解的是,自定义平面坐标系工具的创建涉及到Geogebra...

    高三数学5平面与平面平行试题

    【平面与平面平行的知识点详解】 在高三数学中,平面与平面平行是一个重要的知识点,它涉及到几何学的基本概念和推理。以下是对这个主题的详细解释: 1. **平面与平面平行的定义**: - 如果两个平面之间没有公共...

    FEM_有限元_有限元平面_有限元平面_平面应力_有限元应力_源码

    《有限元方法:平面应力与平面应变问题详解》 有限元方法(Finite Element Method,简称FEM)是计算工程和应用数学中的一个重要工具,它能够有效地解决各种复杂的工程问题,如结构力学、流体力学等领域的计算。在这...

    2021_2022学年高中数学第二章点直线平面之间的位置关系2.3.2平面与平面垂直的判定课后篇巩固提升作业含解析新人教A版必修

    以上是对题目内容涉及的数学知识点的详细解释,主要涵盖平面与平面垂直的判定、二面角的概念及其计算、三棱锥的性质、平面的位置关系、线面夹角的计算以及几何图形的翻折问题。这些知识点是高中数学中的基础内容,...

Global site tag (gtag.js) - Google Analytics