Plane nearest point pair problem, divide and conquer, sorting optimization, merge sort, insertion sort

    The recent point pairing problem involves sorting the points in ascending order by x or y. The author tries to optimize the sorting method. The first thing that comes to mind is naturally merge sort. After all, the core idea of ​​merge sort is also the divide and conquer method, but merge sort is more suitable for cases with more cardinality. Finally, the author changed the idea as follows: when the value of the total number of points n is less than 50, the insertion sort is used, and when the value of n is greater than 50, the merge sort is used. The code is as follows:

void MergeSort(point *a, int p, int r,bool sort_x_y)
{
	if ((rp)>=50) // Insertion sort for arrays with less than 50 data
	{
		int q = (p+r)/2;
		MergeSort(a, p, q,sort_x_y);
		MergeSort(a, q+1, r),sort_x_y;
		Merge(a, p, q, r,sort_x_y);
	}else
	{
		InsertionSort(a+p, r-p+1,sort_x_y);
	}
}
double ClosestPoint(point s_array[],int low,int high,point min_point[]){
    double d1,d2,d3,d;
    int mid,i,j,index;
    double x1,y1,x2,y2; //Record the position of the point pair
    point P[high-low+1],temp1[2],temp2[2]; //auxiliary space
    if(high-low==1){ //The case of two points
        min_point[0].x=s_array[low].x;min_point[0].y=s_array[low].y;
        min_point[1].x=s_array[high].x;min_point[1].y=s_array[high].y;
        return Points_Distance(s_array[low],s_array[high]);
        }
    if(high-low==2){ //The case of three points
        d1=Points_Distance(s_array[low],s_array[low+1]);
        d2=Points_Distance(s_array[low+1],s_array[high]);
        d3=Points_Distance(s_array[low],s_array[high]);
        if((d1<d2)&&(d1<d3)){
            min_point[0].x=s_array[low].x;min_point[0].y=s_array[low].y;
            min_point[1].x=s_array[low+1].x;min_point[1].y=s_array[low+1].y;
            return d1;
        }
        else if(d2<d3){
            min_point[0].x=s_array[low+1].x;min_point[0].y=s_array[low+1].y;
            min_point[1].x=s_array[high].x;min_point[1].y=s_array[high].y;
            return d2;
        }
        else {
            min_point[0].x=s_array[low].x;min_point[0].y=s_array[low].y;
            min_point[1].x=s_array[high].x;min_point[1].y=s_array[high].y;
            return d3;
        }
    }
    mid=(low+high)/2; //Recursive in other cases
    d1=ClosestPoint(s_array,low,mid,min_point);
    temp1[0]=min_point[0];
    temp1[1]=min_point[1];
    d2=ClosestPoint(s_array,mid+1,high,min_point);
    temp2[0]=min_point[0];
    temp2[1]=min_point[1];
    if(d1<d2){
        d=d1;
        min_point[0]=temp1[0];
        min_point[1]=temp1[1];
    }
    else {
        d=d2;
        min_point[0]=temp2[0];
        min_point[1]=temp2[1];
    }
    index=0;
    for(i=mid;(i>=low)&&((s_array[mid].x-s_array[i].x)<d);i--)      //点集合p1
        P[index++]=s_array[i];
    for(i=mid+1;(i<=high)&&((s_array[i].x-s_array[mid].x)<d);i++)      //点集合p2
        P[index++]=s_array[i];
    MergeSort(P,P+index,Assist_y); //Ascending order
    for(i=0;i<index;i++){
        for(j=j+1;j<index;i++){
            if((P[j].y-P[i].y)>=d)
                break;
            else {
                d3=Points_Distance(P[i],P[j]);
                if(d3<d){
                    min_point[0].x=P[i].x;min_point[0].y=P[i].y;
                    min_point[1].x=P[j].x;min_point[1].y=P[j].y;
                    d=d3;
                }
            }
        }
    }
    return d;
}
int main(){ //set of set points
    int n,dimension;
    double min_distance;
    cout<<"Number of input points:\n"; //Number of input points
    cin>>n;
    point s_array[n];
L1: cout<<"Please input the plane where the point is located (1-dimensional input 1, 2-dimensional input 2): ";
	cin>>dimension;
	if(dimension==1)
	    for(int i=0;i<n;i++)
	    {
	    	cout<<"Please enter the distance of the "<<i+1<<" point from the origin"<<endl;
	        cin>>s_array[i].x;
	        s_array[i].y=0;
	    }
 	else if(dimension==2)
	    for(int i=0;i<n;i++)
	    {
	    	cout<<"Please enter the coordinates of the "<<i+1<<" point (separated by spaces)"<<endl;
	        cin>>s_array[i].x>>s_array[i].y;
	    }
  	else
  	{
  		cout<<"The input plane is invalid"<<endl;
		  goto L1;
  	}
    MergeSort(s_array,s_array+n,Assist_x);   
    point min_point[2];
    min_distance=ClosestPoint(s_array,0,n-1,min_point);
    cout<<"最小距离点对为:("<<min_point[0].x<<","<<min_point[0].y<<"),("<<min_point[1].x<<","<<min_point[1].y<<")";
    cout<<"The minimum distance is:\n"<<min_distance;      
    return 0;
}

    The author did not give the InsertionSort() and Merge() functions, because the amount of code of these two functions is larger than expected, and the sorting according to x/y needs to be judged, and function overloading needs to be performed. Here the author recommends the sort() function to everyone, just use #include <algorithm> sort to use it. The sorting method it uses is similar to the quicksort method. The time complexity is n*log2(n), and the execution efficiency is higher.

    For example, in the above author's code, only two functions need to be added as follows:

bool Assist_y(point a,point b){ //sort by y ascending
    return a.y<b.y;
}
bool Assist_x(point a,point b){ //sort by x ascending
    return a.x<b.x;
}

    transfer:

sort(s_array,s_array+n,Assist_x);//In ascending order by x
sort(s_array,s_array+n,Assist_y);//In ascending order by y

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326045412&siteId=291194637