算法设计与分析实验 最近点对-分治法与蛮力法

#include<iostream>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<utility>
#include<climits>
#define endl "\n"
#define inf INT_MAX
using namespace std;
struct point{
	int x,y;
}s[101];
bool compx(point a,point b){
	return a.x<b.x;
}
bool compy(point a,point b){
	return a.y>b.y;
}

double Distance(point a,point b){
	double dx=a.x-b.x;
	double dy=a.y-b.y;
	double dis=sqrt(dx*dx+dy*dy);
	return dis;
}
pair<point,point> Closest(point S[],int low,int high){
	double d1,d2,d3,d;
	pair<point,point> o1,o2,o3,o;
	int min,i,j,index;
	point P[101];		//存放点集合P1和P2
	if(high-low==1){	//只有两个点,返回两点之间的距离 
		o.first=S[low];
		o.second=S[high];
		return o;
	}
	if(high-low==2){	//只有三个点,求最近对距离
		d1=Distance(S[low],S[low+1]);
		d2=Distance(S[low+1],S[high]);
		d3=Distance(S[low],S[high]);
		if((d1<d2)&&(d1<d3)){
			o1.first=S[low];
			o1.second=S[low+1];
			return o1;
		}else if(d2<d3){
			o2.first=S[low+1];
			o2.second=S[high]; 
			return o2;
		}else{
			o3.first=S[low];
			o3.second=S[high]; 
			return o3;
		}
	}
	int mid=(low+high)/2;//计算中间点 当high-low==1 mid=low,mid+1=high但这种情况已经在上面被返回了 
	o1=Closest(S,low,mid);	//递归求解子问题① 
	o2=Closest(S,mid+1,high);	//递归求解子问题②
	d1=Distance(o1.first,o1.second);
	d2=Distance(o2.first,o2.second);
	if(d1<=d2){
		d=d1;
		o=o1;
	}else{
		d=d2;
		o=o2;
	}
	index=0;
	for(i=mid;(i>=low)&&(S[mid].x-s[i].x<d);i--){//建立点集合P1
		P[index++]=S[i];	
	} 
	for(i=mid+1;(i<=high)&&(S[i].x-s[i].x<d);i++){//建立点集合P2
		P[index++]=S[i];
	}
	sort(P,P+index,compy);	//对集合P1和P2按y坐标升序排列
	for(i=0;i<index;i++){	//依次处理集合P1和P2中的点
		for(j=i+1;j<index;j++){
			if(P[j].y-P[i].y>=d){	//超出y坐标的范围,点p[i]处理完毕
				break; 
			}else{
				d3=Distance(P[i],P[j]);
				o3.first=P[i];
				o3.second=P[j];
				if(d3<d){
					d=d3;
					o=o3;
				} 
			}
		}
	}
	return o;
}

int main(){
	srand(time(NULL));
	int n;
	cout<<"Please input the number of points.\n";
	cin>>n; 
	for(int i=0;i<n;i++){
		s[i].x=rand()%1000;
		s[i].y=rand()%1000;
		cout<<s[i].x<<" "<<s[i].y<<endl;
	}
	cout<<"to sort"<<endl;
	sort(s,s+n,compx);	//对集合P1和P2按y坐标升序排列
	for(int i=0;i<n;i++){
		cout<<s[i].x<<" "<<s[i].y<<endl;
	}
	cout<<"have sorted"<<endl;
	pair<point,point> o;
	cout<<"Divide and conquer\n";
	o = Closest(s,0,n);
	double mind,mind1;
	mind = Distance(o.first,o.second);
	cout<<mind<<endl;
	cout<<"("<<o.first.x<<", "<<o.first.y<<")\n";
	cout<<"("<<o.second.x<<", "<<o.second.y<<")\n";
	cout<<"brute force method\n";
	mind1=2*mind;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(i!=j){
				if(Distance(s[i],s[j])<mind1){
					o.first=s[i];
					o.second=s[j];
					mind1 = Distance(s[i],s[j]);
				}
			}
		}
	}
	cout<<mind<<endl;
	cout<<"("<<o.first.x<<", "<<o.first.y<<")\n";
	cout<<"("<<o.second.x<<", "<<o.second.y<<")\n";
	return 0;
} 

请添加图片描述
请添加图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值