分治策略之最近点对问题
2016-09-24 19:04
204 查看
分治策略之最近点对问题
问题:在平面给定N个点,求点对间最近距离。分析:我们知道直线上找出2个最近的点,时间复杂度是O(NlogN),平面上比较所有的点对,直观上我们可以知道时间复杂度是O(N^2)。思考一下,当N非常大的时候,那不是得运算很久,有没有快速算法呢?我们采用分治策越,N个点我们不会做,我们进行Divide,分成两个子问题,N/2个点,依次进行下去。在子问题求出最小解,再回头进行Combine。求解程序如下:
%INPUT: x: 点的x坐标 y :点的y坐标 %OUTPUT: result:min_euclidean distance function [ result ] = Least_Euclidean_Distance( x,y ) if( length(x)==2 )%只有两个点 result=sqrt( (x(1)-x(2))^2+(y(1)-y(2))^2); elseif(length(x)==0 ||length(x)==1 ) result=Inf; else %按x的大小将点对进行排序 [x1,k]=sort(x,'ascend'); for i=1:length(x) y1(i)=y(k(i)); end %中线 middle=(min(x1)+max(x1))/2; hold on; plot([middle,middle],[0,100],'y-','linewidth',1); %将平面分割,直线左边的点放在L数组里,直线右边的点放在R数组里 k=1;j=1; for i=1:length(x1) if(x1(i)<=middle) Lx(k)=x1(i); Ly(k)=y1(i); k=k+1; else Rx(j)=x1(i); Ry(j)=y1(i); j=j+1; end end delta1=Least_Euclidean_Distance(Lx,Ly ); delta2=Least_Euclidean_Distance( Rx,Ry ); delta=min(delta1,delta2); %再进行接合找出[middle-delta middle+delta]之间的点对 %找出条带范围的点 50-delta<X<50+delat范围内再与delta进行比较 k=0; middle_X=[]; for i=1:length(x) if(x(i)>=middle-delta & x(i) <=middle+delta ) k=k+1; middle_X(k)=x(i); middle_Y(k)=y(i); end end [m n]=size(middle_X); min_value=delta; for i=1:n-1 for j=i+1:n temp_distance= sqrt( (middle_X(j)- middle_X(i))^2+(middle_Y(j)-middle_Y(i))^2 ); if(temp_distance<min_value) flag_first=i; flag_second=j; min_value=temp_distance; end end end result=min_value;; end end
总结:Divide and Conquer思想在逆序对数、最近点对、矩阵乘法、FFT领域应用都非常广。最重要的思想是一个问题可以分成两个子问题,假设每个子问题能被解决,实现方法是采用递归调用,再合并两个子问题得到原问题的求解。
相关文章推荐
- 递归与分治策略——集合划分问题,众数问题
- 分治策略之棋盘覆盖问题(ChessBoard)
- zoj2107 最近点对问题 分治思想
- HDU 1007 二维最近点对问题 / 分治
- 算法导论:分治策略__最大子数组问题
- 最近点对问题的分治算法分析与实现
- Java语言描述:递归与分治策略之全排列问题
- 最近点对问题(分治)
- 杭电1007————最近点对问题(分治问题)
- 分治策略算法之最大字数组和问题
- 最近点对问题(分治思想的经典应用)
- zoj 2107 Quoit Design(最近点对问题,好好思考,分治)
- 算法导论C语言实现: 分治策略 -- 最大子数组问题
- 分治法-最近距离问题Java实现
- 第四章 分治策略 4.1 最大子数组问题 (暴力求解算法)
- 分治策略 求两同长数组的中位数问题
- SYSVOL 共享后的最近 24 小时内出现了警告或错误事件。 失败的 SYSVOL 复制问题可能导致组策略问题
- HDU1007——二维空间最近点对问题(分治)
- C语言分治(1)___平面最近点对问题
- 分治策略——最大子数组问题