分治法求点集中的最小距离 version 0.2

来源:互联网 发布:egd网络小黄金 编辑:程序博客网 时间:2024/06/06 09:02
////  main.cpp//  MinPointDistance////  Created by 孙江涛 on 13-9-29.//  Copyright (c) 2013年 bryan. All rights reserved.//#include <iostream>#include <vector>#include <math.h>#include <time.h>using std::cin;using std::cout;using std::endl;using std::vector;using std::sort;struct Point{    double x;    double y;};struct Result{    Point p1;    Point p2;    double distance;};bool sortTwoPointByX(const Point &p1,const Point &p2){    return p1.x < p2.x;}bool sortTwoPointByY(const Point &p1,const Point &p2){    return p1.y < p2.y;}void sortPointVecByX(vector<Point> &pointVec){    sort(pointVec.begin(),pointVec.end(),sortTwoPointByX);}void sortPointVecByY(vector<Point> &pointVec){    sort(pointVec.begin(),pointVec.end(),sortTwoPointByY);}void divideVector(vector<Point> &pointVec,vector<Point> &pointVec0,vector<Point> &pointVec1){    size_t size = pointVec.size();    for(vector<Point>::iterator it = pointVec.begin();it < pointVec.begin()+size/2;++it )    {        Point p;        p.x = (*it).x;        p.y = (*it).y;        pointVec0.push_back(p);    }        for(vector<Point>::iterator it = pointVec.begin()+size/2;it < pointVec.end();++it )    {        Point p;        p.x = (*it).x;        p.y = (*it).y;        pointVec1.push_back(p);    }    }double PointDistance(Point p1,Point p2){    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}double MinPointDistance(double d1,double d2){    if(d1>=0&&d2>=0)    {if(d1 - d2 <= 0)        return d1;        if(d1 - d2 >0)        return d2;}        if(d1>=0&&d2<0)    {        return d1;    }    if(d1<0&&d2>=0)    {        return d2;    }        return 0;}Result MinDistanceInSet(vector<Point> &pointVec){    size_t size= pointVec.size();    Result r;    if(2 == size)    {        r.p1 = pointVec[0];        r.p2 = pointVec[1];        r.distance = PointDistance(pointVec[0],pointVec[1]);        return r;    }    else if(3 == size)    {        double dis01 = PointDistance(pointVec[0], pointVec[1]);        double dis12 = PointDistance(pointVec[1], pointVec[2]);        double dis02 = PointDistance(pointVec[0], pointVec[2]);                double dis = MinPointDistance(dis01, MinPointDistance(dis12, dis02));                if(dis-dis01 == 0)        {            r.p1 = pointVec[0];            r.p2 = pointVec[1];            r.distance = dis01;            return r;                    }        else if(dis-dis02 == 0)        {            r.p1 = pointVec[0];            r.p2 = pointVec[2];            r.distance = dis02;            return r;                    }        else if(dis-dis12 == 0)        {            r.p1 = pointVec[1];            r.p2 = pointVec[2];            r.distance = dis12;            return r;                    }            }    else if(size>=4)    {        sortPointVecByX(pointVec);                vector<Point> pointVec0;        vector<Point> pointVec1;                divideVector(pointVec, pointVec0, pointVec1);                        Result rPointVec0 = MinDistanceInSet(pointVec0);        Result rPointVec1 = MinDistanceInSet(pointVec1);                double minDistanceInTwoPart = MinPointDistance(rPointVec0.distance,rPointVec1.distance);                if(minDistanceInTwoPart - rPointVec0.distance == 0)        {            r.distance = minDistanceInTwoPart;            r.p1 = rPointVec0.p1;            r.p2 = rPointVec0.p2;        }        else if(minDistanceInTwoPart - rPointVec1.distance == 0)        {            r.distance = minDistanceInTwoPart;            r.p1 = rPointVec1.p1;            r.p2 = rPointVec1.p2;        }                Point middlePoint = pointVec[size/2];                vector<Point> pointVec2;        for (vector<Point>::iterator it = pointVec.begin(); it<pointVec.end(); ++it)        {                        Point p;            p.x = (*it).x;            p.y = (*it).y;            if(fabs(p.x-middlePoint.x) < minDistanceInTwoPart && p.x!= middlePoint.x)            {                pointVec2.push_back(p);            }        }                sortPointVecByY(pointVec2);                Result rPointVec2 = MinDistanceInSet(pointVec2);        double minDistance = MinPointDistance(rPointVec2.distance, minDistanceInTwoPart);        if(minDistance - rPointVec2.distance == 0)        {            r.distance = minDistance;            r.p1 = rPointVec2.p1;            r.p2 = rPointVec2.p2;                    }                return r;            }        r.p1.x = 0;    r.p1.y = 0;    r.p2.x = 0;    r.p2.y = 0;    r.distance = -1;        return r;}int main(int argc, const char * argv[]){    vector <Point> pointVec;    vector <Point> pointVec0;    vector <Point> pointVec1;        long N = 100000;    Point p;    srand(time(NULL));    while((N--)>0)    {                        double x = rand()%100000;        double y = rand()%100000;        p.x = x;        p.y = y;                pointVec.push_back(p);    }        clock_t t1 = clock();    Result result = MinDistanceInSet(pointVec);    clock_t t2 = clock();    clock_t t = t2-t1;        cout<<"最近点对的坐标为:"<<endl;    cout<<"P1:( "<< result.p1.x<<","<<result.p1.y<<")"<<endl;    cout<<"P2:( "<< result.p2.x<<","<<result.p2.y<<")"<<endl;    cout<<"最近点对的距离为:"<<result.distance<<endl;    cout<<"耗时"<<t/CLOCKS_PER_SEC<<endl;            return 0;}

原创粉丝点击