精华内容
下载资源
问答
  • 算法-分治法-最近对问题

    千次阅读 多人点赞 2019-03-11 21:23:50
    蛮力法的最近对问题:https://blog.csdn.net/qq_40452317/article/details/88040973 用分治法解决问题就是将集合s分为两个集合s1和s2。每个解合都有n/2个点,接着在子集和中递归求解最近的点。 一维情况 为了简单...

    蛮力法的最近对问题:https://blog.csdn.net/qq_40452317/article/details/88040973

    用分治法解决问题就是将集合s分为两个集合s1和s2。每个解合都有n/2个点,接着在子集和中递归求解最近的点。

    一维情况

    为了简单化问题,我们先考虑一维情形,即所有的点都在x轴上(假如顺序是有序的,也可以排好序,为简单,直接输入有序序列),x轴上某个点m将集合划分为s1和s2,并且两个集合的点数都是相同的,递归的求解两个子集最近对的点,(p1,p2)和(q1,q2)。如果,两个集合的最近点对都在子集s1和s2中,则

                                                              d = min{ |p1-p2| , |q1-q2| } 

    如果,最近点对分别在s1和s2中,则一定是(p3,q3)。|p3-q3|<d,则p3和q3两者与m的距离都不超过d,且在区间(m-d,d]和(d,m+d]各有且仅有一个点。这样,就可以在线性时间内实现合并。

                           

    一维情形下的最近点对时间复杂度为O(nlogn)。

    二维情况

    推广一维,来看二维,我们仿照一维的情况先把所有点按照x(横坐标)从左到右升序排列。以X横坐标中间的点作为分界线.将平面的点分成左边和右边。找到左边的点中最近点对的距离d1,和右边最近点对的距离d2。d=min{d1,d2}。如下如:

                        

    当前的d1,d2都是两边各自的点的最近距离,但是没有考虑到两边的点相互配对的情况,即是点对一个在左边区域,一个在右边区域。可以用上面找到的d来限制配对.即是明显超过d的两点不需要配对,如下

                                                   

    以中间线为中心,dmin 为半径划分一个长带,最小点对还有可能存在于s1和s2的交界处,,p点和q点分别位于S1和S1的虚线范围内,只有在这个范围内,p点和q点之间的距离才会小于dmin。

    不选取2dmin 带中所有的点进行计算,而是对于S1虚框范围内的p点,只选取S2虚框范围内长2dmin,宽为dmin的中的点进行计算,由dmin的意义可知S2中任何2个S中的点的距离都不小于d。由此可以推出矩形R中最多只有6个S2中的点。

     

                                                     

    为什么只有六个点?

    我们利用反证法证明:

    如果右边这2个正方形内有7个点与p点距离小于d,例如q点,则q点与下面正方形的四个顶点距离小于d,则和d为S1和S2中的最小点对距离相矛盾。因此对于S1虚框中的p点,不需求出p点和右边虚线框内所有点距离,只需计算S2中与p点y坐标距离最近的6个点,就可以求出最近点对,节省了比较次数。

                              

    然后我们只知道对于S1中每个d中的点p最多只需要检查S2中的6个点,但是我们并不确切地知道要检查哪6个点。为了解决这个问题,我们可以将p和S2中所有d的点投影到中界线上。由于能与p点一起构成最接近点对候选者的d中点一定在矩形R中,所以它们在直线l上的投影点距p在中界限上投影点的距离小于d。由上面的分析可知,这种投影点最多只有6个。因此,若将S1和S2中所有S的点按其y坐标排好序,则对S1中所有点p,对排好序的点列作一次扫描,就可以找出所有最接近点对的候选者,对S1中每一点最多只要检查S2中排好序的相继6个点。

    算法代码

    一、输入:按x坐标排列的n(n>=2)个点的集合S={(x1,y1),(x2,y2),...,(xn,yn)}

    1.如果n==2,则返回(x1,y1)和(x2,y2)之间的距离,算法结束;

    2.如果n==3,则返回(x1,y1)、(x2,y2)和(x3,y3)之间的最小距离,算法结束;(此步必要在于,若n==3划分之后必然有一半为n==1,导致无法正确执行递归)

    3.划分:m==S中各点x坐标的中位数;

    4.d1 = 计算{(x1,y1),...,(xm,ym)}的最近对距离;

    5.d2 = 计算{(xm,ym),...,(xn,yn)}的最近对距离;

    6.d = min(d1,d2);

    7.依次考察集合S中的点p(x,y),如果(x<=xm 并且x>=xm-d),则将点p放入集合P1中;如果(x>xm 并且x<=xm+d),则将点p放入集合P2中;

    8.将集合P1和P2按y坐标升序排列;

    9.对集合P1和P2中的每个点p(x,y),在y坐标区间[y,y+d]内最对取出6个候选点,计算与点p的最近距离d3;

    10.返回min{d,d3};

    二、输出:最近点的距离

    蛮力法

    (手动输入的时候也会占用时间,所以用文件输入)https://blog.csdn.net/qq_40452317/article/details/88040973: 

                                  

     

    现在使用分治法:

    sort排序的函数使用方法:https://www.cnblogs.com/TX980502/p/8528840.html

    #include<iostream>
    #include<math.h>  //计算距离
    #include<time.h>  //计算运行时间
    #include<fstream>  //文件操作
    #include<algorithm>  //排序
    
    using namespace std;
    #define MAX 0x3f3f3f3f  //定义无穷大
    #define M 99999
    
    struct point {
      double x, y;
    }p[M];
     
    int a[M];// 保存排序的索引
     
    int cmpx(const point& a, const point& b)  //排序升序
    {  
      return a.x < b.x;
    }
     
    int cmpy(int &a, int &b)   //排序升序
    {
      return p[a].y < p[b].y;
    }
     
    inline double min(double a, double b)   //返回两个值中较小的
    {
    	return a < b ? a : b;
    }
    inline double dist(const point& a, const point& b)
    {
      return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
    }
    double closeset(int low, int high)
    {
    	if (low == high)   
    		return MAX;
    	if (low + 1 == high)  //即n=2,返回两点之间的距离
    		return dist(p[low], p[high]);
    	int mid = (low + high)>>1;  //右移一位,相当于除以2,但右移的运算速度更快,若使用(low+high)/2求中间位置容易溢出
    	double ans = min(closeset(low, mid), closeset(mid+1, high));  //递归求出两边最小距离
    	int i, j, c = 0;
    	for (i = low; i <= high; i++) //统计那些点位于两虚线内,并记录
    	{
    		if (p[mid].x - ans <= p[i].x && p[i].x <= p[mid].x + ans)
    			a[c++] = i;
    	}
    	sort(a, a + c, cmpy);
    	for(i = 0; i < c; i++)//比较s1中虚线内的点和s2中虚线内的点的距离是否存在有小于两侧最小对的
    	{
    		int k = i+7 > c ? c : i+7;  
    		for (j = i+1; j < k; j++)
    		{
    			if (p[a[j]].y - p[a[i]].y > ans)  //如果位于中位线两侧的点的距离大于anx则跳出第一个循环
    				break;
    			ans = min(dist(p[a[i]], p[a[j]]), ans);   //如果有两个点小于两侧的最近对,则选出最小的点
    		}
    	}
    	return ans;
    }
    
    int main()
    {
    	clock_t start;
    	double totaltime;
    	start=clock();
    	int n;  //一共多少个点
    	double dmin;
    	ifstream read_in;
    	read_in.open("close.txt");
    	read_in >> n;
    	cout<<"读入点数为:"<<n<<endl;
    	cout<<"点的坐标为:"<<endl;
    	for(int i=0;i<n;i++)  //循环读入文件
    	{
    		cout<<"p"<<i+1<<":";
    		read_in>>p[i].x>>p[i].y;
    		cout<<p[i].x<<" "<<p[i].y<<endl;
    	}
    	sort(p,p+n,cmpx); //按照x轴排序
    	dmin=closeset(0, n-1);
    	cout<<"最近的距离是:"<<dmin<<endl;
    	clock_t end=clock();
    	totaltime=(double)(end-start)/CLOCKS_PER_SEC;
    	cout<<"程序运行时间是:"<<totaltime<<endl;
    	return 0;
    }
    

                                   

     

    可以看出,分治法的时间是0.008,蛮力法的时间是0.012。如果点数达到一定多,效率更加明显。

    展开全文
  • 算法-蛮力法-最近对问题

    千次阅读 2019-02-28 19:23:48
    最近对问题 在n个点中,距离最近的两个点,在二维坐标平面中,两点分别是a(x1,y1),b(x2,y2),则两点距离是 d=sqrt((x1-x2)^2+(y1-y2)^2) 蛮力法,将平面内的n个点,两两组队,计算最小距离,注意,这儿...

     最近对问题

              在n个点中,距离最近的两个点,在二维坐标平面中,两点分别是a(x1,y1),b(x2,y2),则两点距离是

                                           d=sqrt((x1-x2)^2+(y1-y2)^2)

              蛮力法,将平面内的n个点,两两组队,计算最小距离,注意,这儿没有方向,也就是说两点之间只需要求解一次就行了,而且考虑的是距离所以可以简化公式,不用开方,直接计算平方就行了。

              其中注意,ind1和ind2这个引用类型,return返回只能返回一个,所以用引用类型变量。

    close.txt

    15
    5 10
    9 1
    10 12
    10 19
    13 15
    15 19
    16 20
    19 9
    24 0
    24 12
    31 32
    32 24
    38 29
    40 56
    45 23

    完整代码:(c++)

    #include<iostream>
    #include<math.h>
    #include<time.h>
    #include<fstream>
    
    using namespace std;
    #define MAX 0x3f3f3f3f  //定义无穷大
    #define M 100
    typedef struct Point
    {
    	int x;
    	int y;
    }P[M];
    
    float ClosePoint(P p,int n,int &ind1,int &ind2)
    {
    	int dmin=MAX,d;
    	for(int i=0;i<n;i++)
    	{
    		for(int j=i+1;j<n;j++)
    		{
    			d=(p[i].x - p[j].x)*(p[i].x - p[j].x) + (p[i].y - p[j].y)*(p[i].y - p[j].y);
    			if(d<dmin)
    			{
    				dmin=d;
    				ind1=i;
    				ind2=j;
    			}
    		}
    	}
    	return dmin;
    }
    int main()
    {
    	clock_t start;
    	double totaltime;
    	start=clock();
    	int ind1,ind2,n;
    	P p;
    	float dmin;
    	ifstream read_in;
    	read_in.open("close.txt");
    	read_in >> n;
    	cout<<"读入点数为:"<<n<<endl;
    	cout<<"点的坐标为:"<<endl;
    	for(int i=0;i<n;i++)
    	{
    		cout<<"p"<<i+1<<":";
    		read_in>>p[i].x>>p[i].y;
    		cout<<p[i].x<<" "<<p[i].y<<endl;
    	}
    	dmin=sqrt(ClosePoint(p,n,ind1,ind2));
    	cout<<"最近的两个点是:"<<"p"<<ind1+1<<" "<<"p"<<ind2+1<<endl;
    	cout<<"最近的距离是:"<<dmin<<endl;
    	clock_t end=clock();
    	totaltime=(double)(end-start)/CLOCKS_PER_SEC;
    	cout<<"程序运行时间是:"<<totaltime<<endl;
    	return 0;
    }
    

    展开全文
  • 最近对问题(蛮力法)

    千次阅读 2018-09-28 18:09:30
    问题描述:最近对问题是求解平面点集n个点中距离最近的两个点间的问题。为简单起见,在二维坐标平面来考虑该问题。如果讨论的点以标准二维坐标形式给出,则有点Pi(Xi,Yi)和Pj(Xj,Yj),二者的两点间距离可以利用公式d...

    问题描述:最近对问题是求解平面点集n个点中距离最近的两个点间的问题。为简单起见,在二维坐标平面来考虑该问题。如果讨论的点以标准二维坐标形式给出,则有点Pi(Xi,Yi)和Pj(Xj,Yj),二者的两点间距离可以利用公式d(Pi,Pj)=√(Xj-Xi)*(Xj-Xi)+(Yj-Yi)*(Yj-Yi)。通过这个公式,可以计算平面上任意两点之间的距离。

    因此,蛮力法求解思路就是对平面n个点两两组队,计算并记录最小距离。

    public class zuijindui {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		AA a=new AA();
    		a.ClosePoint();
    	}
    
    }
    class AA{
    	int x[]={0,2,4,1,1};
    	int y[]={0,1,2,3,1};
    	int i,j;
    	int n=x.length;
    	int ind1=0,ind2=0;
    	int dis;
    	int mind=9999;
    	void ClosePoint() {
    		for(i=0;i<n-1;i++) {
    			for(j=i+1;j<n;j++) {
    				dis=(x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i]);
    				if(dis<mind) {
    					mind=dis;
    					ind1=i;
    					ind2=j;
    				}
    			}
    		}
    		System.out.println("第一个点的坐标为:("+x[ind1]+","+y[ind1]+")");
    		System.out.println("第二个点的坐标为:("+x[ind2]+","+y[ind2]+")");
    //		System.out.println(mind);
    	}
    }

    结果:

    第一个点的坐标为:(2,1)
    第二个点的坐标为:(1,1)
     

    展开全文
  • 蛮力法之最近对问题(C实现)

    千次阅读 2015-11-07 21:02:06
    #include #include <math.h> /* 我们可以避免求平方根,窍门是忽略平方根函数,而只比较(x[i]-x[j])^2+(y[i]-y... printf("最近的距离为:%d\n",BruteForceClosestPoints(n)); return 0; } 运行效果图
    #include <stdio.h>
    #include <math.h> 
    
    /*
    	我们可以避免求平方根,窍门是忽略平方根函数,而只比较(x[i]-x[j])^2+(y[i]-y[j])^2的值本身。 
    */ 
    
    int BruteForceClosestPoints(int n) {
    	int d=1000, i, j, t, x[100], y[100];
    	for (i= 1; i < n + 1; i++) {
    		printf("输入x[%d]和y[%d]:", i, i);
    		scanf("%d%d", &x[i], &y[i]);
    	}
    	for (i = 1; i < n; i++) 
    		for (j=i+1; j < n+1; j++) {
    			t = (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
    			if (d*d > t) {
    				d = t;
    			}
    				
    		} 	
    	return sqrt(d);
    }
    
    int main() {
    	int n, p[100];
    	printf("输入点的个数:");
    	scanf("%d", &n);
    	printf("最近的距离为:%d\n",BruteForceClosestPoints(n));
    	return 0;
    }

    运行效果图


    展开全文
  • 分治法-最近对问题

    千次阅读 2016-03-26 21:38:02
    问题描述: ...用m=(low+high)/2,讲点划分为两部分,d1=左半部分点的最近距离,d2=右半部分点的最近对距离,d=min(d1,d2)。还需考虑在中线两边的点的最近距离,且只用考虑与中线距离#include #includ
  • 【算法设计与分析】分治法与最近对问题

    千次阅读 多人点赞 2018-10-15 17:26:32
    说明:这是武汉理工大学...设,,…,是平面上n个点构成的集合S,最近对问题就是找出集合S中距离最近的点对。 严格地讲,最接近点对可能多于一对,简单起见,只找出其中的一对作为问题的解。 二、问题分析 用分治...
  • 分治——最近对问题

    万次阅读 多人点赞 2018-09-28 15:55:04
    利用分治方法的经典问题——最近对问题(Closest pair of points problem) 问题描述 n个点在公共空间中,求出所有点对的欧几里得距离最小的点对。 问题分析 该题直观的解决方法便是Brute Force(暴力求解)...
  • c语言 最近对问题(分治法+递归)

    千次阅读 多人点赞 2019-07-14 21:26:28
    就是在一条直线上,寻找最近的距离,这个我们其实可以进行直接的循环比较,简单说来就是先拿一个点,让它与其他(n-1)个点计算距离,每次比较存储最小即可。但这样效率太低了,时间复杂度分分钟都到O(n^2)上去...
  • 算法分析与设计——最近对问题

    万次阅读 多人点赞 2016-11-26 14:54:24
    【问题描述】最近对问题要求在包含有n个点的集合S中,找出距离最近的两个点。设 p1(x1,y1),p2(x2,y2),……,pn(xn,yn)是平面的n个点。严格地将,最近点对可能不止一对,此例输出一对即可。 【基本算法思想】暴力法...
  • c语言 分治法求解最近对问题

    千次阅读 2018-10-22 21:13:33
    最近对问题(二维平面上的点),编程实现用分治法求解。 最近点对算法: double cpair2(S) {  n=|S|;  if (n &lt; 2) return 0; 1)、m=S中各点x坐标的中位数;  //构造S1和S2;  S1={p∈S|x(p)&...
  • 用分治法求解最近对问题

    千次阅读 2020-03-28 21:32:49
    一、求解最近对问题 【问题描述】给定平面S上n个点,找其中的一对点,使得在n个点组成的所有点对中,该点对间的距离最小。 (1)蛮力法求解最近对问题 double ClosestPoints(vector<Point> a,int ...
  • 最近对问题(分治法)

    千次阅读 多人点赞 2020-04-23 16:46:56
    问题描述 给定平面S上n个点,找其中的一对点,使得在n个点组成的所有点中,该点间的距离最小 蛮力法求解 点的存储: class Point{ //横坐标 int x; //纵坐标 int y; /** * 求解两个坐标之间的...
  • 分治法解决最近对问题

    万次阅读 2018-07-04 11:23:09
    问题 给定平面上n个点,找其中的一对点,使得在n个点的所有点中,该点的距离最小。严格地说,最接近点可能多于1。为了简单起见,这里只限于找其中的一对。原理(这段为抄袭...
  • 讲解分治法求最近对问题的思想与算法实现。 利用分治法求最近点对与归并排序的结构上的相同,将时间复杂度降到真正意义上的O(nlogn)而不是O(nlognlogn)。 1. 预处理:创建结构体Node附带属性x,y表示在平面...
  • 最近对问题python解法

    千次阅读 2017-12-29 08:45:16
    OUTPUT: 欧式距离最近的点 最原始想法:遍历所有点的集合,具有o(n^2)的时间复杂度 可以使用分治思想进行算法优化. 首先将所有点按照X轴排序(Y轴也可以),之后进行分割为左一半元素,右一半元素,最后左右分别求...
  • 算法分析:求最近对问题(c++)

    万次阅读 2017-11-18 01:14:58
    算法分析:求最近对问题(c++)1、 准备部分: 对于最近点问题,需要将问题代码化,所以要先创建一个点类,来使得计算使用时候更加方面,class Points //点类 { public: float x; float y; };因为会多次计算...
  • 最近对问题说来其实很简单,主要就是在二维平面内的n个点中,找出(欧式)距离最近的两个点来。 问题解决思路: 解决这个问题最直接的方法就是“蛮力法”(Brute Force)了,其实现过程即为: 计算出二维平面...
  • 最近对问题? 设p1=(x1,y1), p2(x2,y2), ....,pn=(xn,yn)是平面上n个点构成的集合S,最近对问题就是找出集合S中距离最近的点对。 两种算法思想: 1. 蛮力法:顾名思义,利用正常的思维,使用强硬的方式求解出结果...
  • Java实现最近问题

    万次阅读 多人点赞 2019-07-15 20:35:56
    **问题描述:** 给定某空间中(直线空间或平面空间)n个点,请找出它们中的最近点对。你需要完成下列任务: 1、随机产生或手工输入n个...(1)直线空间求最近对问题最近点对如果直接用蛮力法,即有n个点,从第...
  • 平面最近对问题求解

    千次阅读 2016-07-25 01:30:49
    平面最近对问题求解问题描述: 最近对问题是指求解平面点集n个点中距离最近的两个点间的问题。为简单起见,在二维坐标平面来考虑该问题。如果说讨论的点以标准二维坐标给出,则有点和,那么这两点之间的距离。...
  • 分治法-最近距离问题Java实现

    千次阅读 2014-08-12 20:38:01
    分治算法,有很多典型的问题,如最近点问题、线性选择...网上找到一些代码,标题如“java 用蛮力法和分治法求解最近对有关问题”,虽然体现了分治,但划分不够彻底,因此我重新对其进行了实现。 一、基本思想及策略:
  • 设S是平面上n个点的集合,在S中找到两点p、q,使得他们的欧几里得距离d(p,q)是所有点中最小的。 朴素的算法是计算所有点的距离,在求出最小的,需要Ω(n2)。 采用分治法可以在Θ(nlogn)完成任务。
  • 平面最近对问题求解—基于Java语言 1. 问题描述: 本问题来自《编程之美2.11—寻找最近点对》,文中给出了两种解法:暴力解法,分治解法。其中,暴力解法很简单,求出所有点之间的距离并做比较,便可找到距离...
  • 平面上求最近对问题

    万次阅读 多人点赞 2012-02-26 16:47:43
    求点集中的最近有以下两种方法: 设p1=(x1, y1), p2=(x2, y2), …, pn=(xn, yn)是平面上n个点构成的集合S,设计算法找出集合S中距离最近的点。   1、蛮力法(适用于点的数目比较小的情况下)  1)算法...
  • 在看算法导论时,遇到一些算法问题,不是很理解。 分治法求最近对问题中,为什么要依据x和y进行排序?
  • 平面最近点距离问题(分治法)

    万次阅读 多人点赞 2017-04-28 11:35:53
    问题描述:给定平面上n个点,每个点坐标分别为(x,y),求其中的一对点,使得在n个点组成的所有点中,该点的距离最小。 最简单的做法是找到所有点的距离,然后求最小值,但这样做效率太低,时间复杂度为O(n*n),...
  • 最近对问题

    万次阅读 多人点赞 2012-09-12 22:52:04
    在二维平面上的n个点中,如何快速的找出最近的一对点,就是最近对问题。  一种简单的想法是暴力枚举每两个点,记录最小距离,显然,时间复杂度为O(n^2)。  在这里介绍一种时间复杂度为O(nlognlogn)的算法。...
  • C语言分治(1)___平面最近对问题

    千次阅读 2014-11-22 16:40:28
    平面最近对问题是指:在给出的
  • 最近对问题:给定平面上的N个点,找出距离最近的两个点。分治法:  1 )如果数组长度(即点的个数,一般≤3)在一定范围内时直接求出最近点,蛮力求解,递归退出条件;  2)求出这些点的X坐标的中位数mid  3)...
  • 寻找最近 目录 寻找最近 问题分析 分治法 时间复杂度 题目:在一个 n≥2n\geq 2 个点的集合 Q 中寻找距离最近的点 问题分析 首先很容易想到暴力破解的方法,但是需要 O(n2n^2) 的时间...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,076,840
精华内容 430,736
关键字:

最近对问题