您的位置:首页 > 其它

分治策略之最近点对问题

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领域应用都非常广。最重要的思想是一个问题可以分成两个子问题,假设每个子问题能被解决,实现方法是采用递归调用,再合并两个子问题得到原问题的求解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: