分治法求最近点对

Dvide and Conquer

Implement the algorithm for the closest pair problem in your favourite language.

INPUT: n points in a plane.

OUTPUT: The pair with the least Euclidean distance.


算法的思想:

首先对所有的点按照x坐标进行从小到大排序,然后利用二分法进行分割,直到区间范围变为2 or 3(即只有2个点或只有3个点),然后可以求这2个点或是3个点的距离(很小的子问题)。

对于每一部分子问题,求其中间mid左右各min范围内的点的距离,如图:

分治法求最近点对_第1张图片

对于这幅图中,只需将绿色的点与右边3个红色的点比较即可(格子按1/2&距离分割,可以保证每个格子内只有1个点)。

分治法求最近点对_第2张图片

对于这幅图,只需将绿色的点与左边6个点比较即可

这里,当我们按照y坐标进行排序后(不考虑x坐标),因此对于每一个点,只需要将其与附近的11个点比较即可。

算法的合并时间:边界附近的点进行排序需要O(nlogn)。

如果每一次迭代保持2个序列,一个按照x进行排序,一个按照y进行排序,像归并排序一样,将预先排序好的2个方向的序列合并起来,实际上只需要0(n)时间。

因此算法的时间复杂度为T(n)=2T(n)+O(n)=0(nlogn)。


input:

-5,-5
-4,-4
-3,-6
-3,-3
-2,-3
-1,-5
0,-3
1,-4
0.5,-3
0.5,-4

output:

分治法求最近点对_第3张图片

#include  
#include
#include
#include 
#include
#include 
using namespace std;
int k=0; 


struct Record
{
	int c1,c2;
	double ds;
}record[10000];


struct Points
{
	double x,y;
}*points;


double dis(int a,int b)
{
	double dx = points[a].x-points[b].x,dy = points[a].y-points[b].y;
	return sqrt(dx*dx+dy*dy);
}


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

   
int cmpx(const Points &a,const Points &b)    
{  
	if(a.x>1);
	double dl = ClosestPair(l,mid);
	double dr = ClosestPair(mid+1,r);
	double Min=min(dl,dr);
	int h1=mid,h2=mid;
	while((points[mid].x-points[h1].x<=Min && h1>=l) || (points[h2].x-points[mid].x<=Min && h2<=r))
	{	//得到mid附近2&距离内的区间范围
		h1--;
		h2++;
	}
	sort(&points[l],&points[r],cmpy); //将mid附近2&距离内的点按照y坐标从小到大排序
	for(int i=h1+1;ih2?h2:(i+11);	//只需要比较附近11个点即可
		for(int j=i+1;j=Min)
				break;
			Min = d;
			storage(d,i,j);
		}
	}
	return Min;
}


int main()
{
	ifstream infile("./points.txt", ios::in); 
    char buf[30];
	double (*data)[2];	
	char *subarr=NULL;
	char *delims = ",";
	int n;
	cout<<"Please input the number of points(eg.input 10 int this test):"<>n;
	points = new struct Points[n];
	data = new double[n][2];
    if(!infile.is_open())
	{
		cout<<"Error opening file!";
		exit(1);
	}
	int i=0,j=0,p=0;
	while(infile.getline(buf,30)!=NULL)
	{
		j = 0;
		subarr = strtok(buf,delims);
		while(subarr!=NULL)
		{
			data[i][j] = atof(subarr);	
			subarr = strtok(NULL,delims);
			j++;
		}
		
		points[p].x = data[i][0];
		points[p++].y = data[i][1];
		i++;
		
	}
	infile.close();
	sort(&points[0],&points[n],cmpx); //按横坐标从小到大排序
	double value = ClosestPair(0,n-1);
	int x,y;
	for(i=0;i


你可能感兴趣的:(算法设计与分析)