zoukankan      html  css  js  c++  java
  • 最接近点对问题(分治法)

     来 自

     http://www.ahhf45.com/info/Data_Structures_and_Algorithms/problems/problem_set/ndp/problem.htm

     

    问题描述

        在应用中,常用诸如点、圆等简单的几何对象代表现实世界中的实体。在涉及这些几何对象的问题中,常需要了解其邻域中其他几何对象的信息。例如,在空中交通控制问题中,若将飞机作为空间中移动的一个点来看待,则具有最大碰撞危险的2架飞机,就是这个空间中最接近的一对点。这类问题是计算几何学中研究的基本问题之一。下面我们着重考虑平面上的最接近点对问题。

    最接近点对问题的提法是:给定平面上n个点,找其中的一对点,使得在n个点的所有点对中,该点对的距离最小。

    严格地说,最接近点对可能多于1对。为了简单起见,这里只限于找其中的一对。

    代码如下:

    #include <iostream>
    #include <fstream>
    #include <math.h>
    using namespace std;
    
    ifstream fin("in.txt");
    struct point
    {
        int x;
        int y;
    }*p;
    
    
    void sort(point *p,int n)
    {
        point t;
        for(int i=1;i<n;i++)
        {
            t = p[i];
            for(int j=i-1;j>=0;j--)
            {
                if(t.x < p[j].x) p[j+1]=p[j];
                else break;
            }
            p[j+1]=t;
        }
    }
    
    double Distance(int i,int j)
    {
        return sqrt((p[j].x-p[i].x)*(p[j].x-p[i].x)+(p[j].y-p[i].y)*(p[j].y-p[i].y));
    }
    
    double Closest(int begin,int end,int &one,int &two)
    {    
        if(end-begin==1)    //两个点的情况
        {
            one = begin; two = begin+1;
            return Distance(begin,end);
        }
        double min,dist; 
        if(end-begin==2)      //三个点的情况
        {
            min = Distance(begin,begin+1);
            one = begin;    two = begin+1;
            dist = Distance(begin,end);
            if(min>dist){min=dist;two = end;}
            dist = Distance(begin+1,end);
            if(min>dist){min=dist;one = begin+1;}
            return min;
        }
    
        int mid = (begin+end)/2;               //多余三个点 分治法求解
        dist = Closest(begin,mid,one,two);
        int three=0,four=0;
        double dist2 =  Closest(mid,end,three,four); 
        if(dist<dist2)                           //对结果合并处理
        {min = dist;}
        else{
            min = dist2;
            one = three; two = four;
        }
        int i,j,num;
        double xia,shang;                  //关键部分!
        xia = p[mid].x-min;
        for(i=mid;i>=0;i--)             
        {
            if(p[i].x<xia)break;
            num = mid+6 < end ? mid+6:end;
            shang = p[i].y+min;
            for(j=mid+1;j<num;j++)
            {
                if(p[j].x-p[i].x > min)break;
                if(p[j].y > shang)continue;
                dist = Distance(i,j);
                if(min>dist)
                {
                    min=dist;
                    one = i;
                    two = j;
                
                }
            }
        }
        return min;
    }
    
    int main()
    {
        int n;
        fin>>n;
        p= (point *)malloc(sizeof(point)*n);
        int i;
        for(i=0;i<n;i++)
        {
            fin>>p[i].x>>p[i].y;
        }
        sort(p,n);
        for(i=0;i<n;i++)
            cout<<p[i].x<<" ";
        cout<<endl;
        int one=0,two=0;
        cout<<"The closest distance is "<<Closest(0,n,one,two)<<endl;
        cout<<"<"<<p[one].x<<","<<p[one].y<<">"<<endl;
        cout<<"<"<<p[two].x<<","<<p[two].y<<">"<<endl;
        return 0;
    }

    输入文件 in.txt:

    10

    43 67
    99 35
    81 36
    64 78
    45 65
    71 94
    24 61
    21 34
    5 29
    31 51

    结果:

    5 21 24 31 43 45 64 71 81 99   //按x轴从小到大排序
    The closest distance is 2.82843
    <43,67>
    <45,65>
    Press any key to continue

  • 相关阅读:
    Maven Nexus 上传jar到本地仓库。
    java Web与Flex通过HTTP service 通信 并解析Map 数据。
    JACOB调用WORD书签修改WORD文档,并生成html显示到页面中
    去除java list 中的 [] 括号
    2019-2020-2 20175222 《网络对抗技术》Exp9 Web安全基础
    2019-2020-2 20175222 《网络对抗技术》 Exp 8 Web基础
    2019-2020-2 20175222 《网络对抗技术》 Exp7 网络欺诈防范
    2019-2020-2 20175222 《网络对抗技术》 Exp6 MSF基础应用
    2019-2020-2 20175222《网络对抗技术》 Exp5 信息搜集与漏洞扫描
    2019-2020-2 20175222罗雨石 《网络对抗技术》 Exp4 恶意代码分析
  • 原文地址:https://www.cnblogs.com/yezhennan/p/5443597.html
Copyright © 2011-2022 走看看