您的位置:首页 > 其它

分治算法 最接近点对(一维)

2015-06-19 16:15 169 查看
最接近点对,在实际应用中有很强的实用性!下面我就介绍一下,怎么求一维的最接近点!二维的会再下一次博客更新!

方法:把所有点从大到小先进行排序,找出最大点MAX和最小点min。然后求mid=(max+min)/2,以mid为 参照点把集合s分成S1和S2.如图:

(1)

有上图可知,最小点对可能存在于S1或S2中的一对点,不妨设这对点的距离是d,还有一种可能就是一个点存在于S1中,一个点存在于S2中,根据已经做好的排序可知,这两个点必定是S1中的最大点p,和S2中的最小点q,所以我们只需要比较(q-p)和d的大小,然后迭代返回,即可。

声明:本篇博客是参考/article/1386229.html这个写的!如果想知道具体的细节,请参考上述网址!下面我附上源代码,只是把上述的代码做了一点变化!(本来想附上java代码,但java代码没有调试成功!遗憾!)
//2d10-1 一维最邻近点对问题
#include <ctime>
#include <stdlib.h>
#include <math.h>
#include <iostream>
using namespace std;

const int L=100;
//点对结构体
struct Pair
{
float d;//点对距离
float d1,d2;//点对坐标
};
float Random();
int input(float s[]);//构造S
float Max(float s[],int p,int q);
float Min(float s[],int p,int q);
template <class Type>
void Swap(Type &x,Type &y);
template <class Type>
int Partition(Type s[],Type x,int l,int r);
Pair Cpair(float s[],int l,int r);

int main()
{
int m;
float s[L];
Pair d;
m=input(s);
d=Cpair(s,0,m-1);
cout<<endl<<"最近点对坐标为: (d1:"<<d.d1<<",d2:"<<d.d2<<")";
cout<<endl<<"这两点距离为: "<<d.d<<endl;
return 0;
}

float Random()
{
float result=rand()%10000;
return result*0.01;
}

int input(float s[])
{
int length;
cout<<"输入点的数目: ";
cin>>length;
cout<<"点集在X轴上坐标为:";
for(int i=0;i<length;i++)
{
s[i]=Random();
cout<<s[i]<<" ";
}

return length;
}

float Max(float s[],int l,int r)//返回s[]中的最大值
{
float s_max=s[l];
for(int i=l+1;i<=r;i++)
if(s_max<s[i])
s_max=s[i];
return s_max;
}

float Min(float s[],int l,int r)//返回s[]中的最小值
{
float s_min=s[l];
for(int i=l+1;i<=r;i++)
if(s_min>s[i])
s_min=s[i];
return s_min;
}

template <class Type>
void Swap(Type &x,Type &y)
{
Type temp = x;
x = y;
y = temp;
}

template <class Type>
int Partition(Type s[],Type x,int l,int r)
{
int i = l - 1,j = r + 1;

while(true)
{
while(s[++i]<x && i<r);
while(s[--j]>x);
if(i>=j)
{
break;
}
Swap(s[i],s[j]);
}
return j;
}

//返回s[]中的具有最近距离的点对及其距离
Pair Cpair(float s[],int l,int r)
{
Pair min_d={99999,0,0};//最短距离

if(r-l<1) return min_d;
float m1=Max(s,l,r),m2=Min(s,l,r);

float m=(m1+m2)/2;//找出点集中的中位数

//将点集中的各元素按与m的大小关系分组
int j = Partition(s,m,l,r);

Pair d1=Cpair(s,l,j),d2=Cpair(s,j+1,r);//递归
float p=Max(s,l,j),q=Min(s,j+1,r);

//返回s[]中的具有最近距离的点对及其距离
if(d1.d<d2.d)
{
if((q-p)<d1.d)
{
min_d.d=(q-p);
min_d.d1=q;
min_d.d2=p;
return min_d;
}
else return d1;
}
else
{
if((q-p)<d2.d)
{
min_d.d=(q-p);
min_d.d1=q;
min_d.d2=p;
return min_d;
}
else return d2;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: