分治策略之最近点对问题

分治策略之最近点对问题

问题:在平面给定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领域应用都非常广。最重要的思想是一个问题可以分成两个子问题,假设每个子问题能被解决,实现方法是采用递归调用,再合并两个子问题得到原问题的求解。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值