最接近点对问题

问题的提出:给定平面上n个点,找其中的一对点,使得在n个点组成的所有点对中,该点对间的距离最小。

方法:分治法。如果组成S的最接近点对的两个点都在S1中或都在S2中,则问题很容易解决。但是,如果这两个点分别在S1和S2中,问题就不那么简单了。

1、一维情形的分治法
可以先把点排好序,然后用一次线性扫描就可以找出最接近点对,但是这种方法无法推广到二维的情形。
在这里插入图片描述

首先,分割点m的选取利用S中各点坐标的中位数来作为分割点。用选取中位数的线性时间算法可以在O(n)时间内确定一个平衡的分割点m。这里使用m=[max(S)+min(S)]/2方法。

分割点m的选取:线性时间选择算法

一维最接近临近点对问题代码:

#include <iostream>
#include <ctime>
#include<cstdlib>
using namespace std;

struct Pair{
	
	float d;  //两点间的距离
	float d1, d2;   //一维上的点对坐标 
};

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

int input(float s[], int length) {
	
	srand((int)time(0));
	cout << "点集在X轴上的坐标: ";
	for(int i = 0; i < length; i++){
		
		s[i] = random_number();
		cout << s[i] << " ";
	}

}

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;	
}

int partition(float a[], int l, int r, float x){
	
	int i = l;
	int j = r + 1;

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

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);
	float m2 = min(s, l, r);
	
	float m = (m1 + m2) / 2;  //找出点集中的中位数 
	
	int j = partition(s, l, r, m);  //以m为基准进行分割
	//递归
	Pair d1 = cpair(s, l, j);
	Pair d2 = cpair(s, j + 1, r);
	 
	float p = max(s, l, j);
	float q = min(s, j + 1, r);
	
	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;
		}
	}
	
}

int main(){
	
	int length;
	cout << "请输入点的数目:";
	cin >> length;
	float s[length];
	input(s, length);  //构造s[]集合 
	
	Pair d;
	d = cpair(s, 0, length-1);
	cout << endl << "最近点对坐标为: (" << d.d1 << ", " << d.d2 << ")";
	cout << endl << "这两点距离为:" << d.d << endl;
	
	return 0;
}	

在这里插入图片描述

2、二维最接近点对问题
未完待续。。。。(博主还写不出这个代码)

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值