`
mingjian01
  • 浏览: 29586 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

(转)最接近点对算法

阅读更多

    这个问题很容易理解,似乎也不难解决。我们只要将每一点与其他n-1个点的距离算出,找出达到最小距离的两个点即可。然而,这样做效率太低,需要O (n2 )的计算时间。在问题的计算复杂性中 我们可以看到,该问题的计算时间下界为Ω (n logn )。这个下界引导我们去找问题的一个θ (n logn )算法。

    这个问题显然满足分治法 的第一个和第二个适用条件 ,我们考虑将所给的平面上n个点的集合S分成2个子集S1 和S2 ,每个子集中约有n/2个点,·然后在每个子集中递归 地求其最接近的点对。在这里,一个关键的问题是如何实现分治法中的合并步骤 ,即由S1 和S2 的最接近点对,如何求得原集合S中的最接近点对,因为S1 和S2 的最接近点对未必就是S的最接近点对。如果组成S的最接近点对的2个点都在S1 中或都在S2 中,则问题很容易解决。但是,如果这2个点分别在S1 和S2 中,则对于S1 中任一点p,S2 中最多只有n/2个点与它构成最接近点对的候选者,仍需做n2 /4次计算和比较才能确定S的最接近点对。因此,依此思路,合并步骤耗时为O (n2 )。整个算法所需计算时间T(n)应满足: 

T(n)=2T(n/2)+O (n2 )

    它的解为T(n)=O (n2 ),即与合并步骤的耗时同阶,显示不出比用穷举的方法好。从解递归方程的套用公式法,我们看到问题出在合并步骤耗时太多。这启发我们把注意力放在合并步骤上。

    为了使问题易于理解和分析,我们先来考虑一维的情形。此时S中的n个点退化为x轴上的n个实数x1 ,x2 ,..,xn 。最接近点对即为这n个实数中相差最小的2个实数。我们显然可以先将x1 ,x2 ,..,xn 排好序,然后,用一次线性扫描就可以找出最接近点对。这种方法主要计算时间花在排序上,因此如在排序算法 中所证明的,耗时为O (n logn )。然而这种方法无法直接推广到二维的情形。因此,对这种一维的简单情形,我们还是尝试用分治法来求解,并希望能推广到二维的情形。

    假设我们用x轴上某个点m将S划分为2个子集S1 和S2 ,使得S1 ={x∈S|x≤m};S2 ={x∈S|x>m}。这样一来,对于所有p∈S1 和q∈S2 有p<q。

    递归地在S1 和S2 上找出其最接近点对{p1 ,p2 }和{q1 ,q2 },并设δ =min{|p1 -p2 |,|q1 -q2 |},S中的最接近点对或者是{p1 ,p2 },或者是{q1 ,q2 },或者是某个{p3 ,q3 },其中p3 ∈S1 且q3 ∈S2 。如图1所示。

 

图1 一维情形的分治法

    我们注意到,如果S的最接近点对是{p3 ,q3 },即|p3 -q3 |<δ ,则p3 和q3 两者与m的距离不超过δ ,即|p3 -m|<δ ,|q3 -m|<δ ,也就是说,p3 ∈(m-δ ,m],q3 ∈(m,m+δ ]。由于在S1 中,每个长度为δ 的半闭区间至多包含一个点(否则必有两点距离小于δ ),并且m是S1 和S2 的分割点,因此(m-δ ,m]中至多包含S中的一个点。同理,(m,m+δ ]中也至多包含S中的一个点。由图1可以看出,如果(m-δ ,m]中有S中的点,则此点就是S1 中最大点。同理,如果(m,m+δ ]中有S中的点,则此点就是S2 中最小点。因此,我们用线性时间就能找到区间(m-δ ,m]和(m,m+δ ]中所有点,即p3 和q3 。从而我们用线性时间就可以将S1 的解和S2 的解合并成为S的解。也就是说,按这种分治策略,合并步可在O (n)时间内完成。这样是否就可以得到一个有效的算法了呢?还有一个问题需要认真考虑,即分割点m的选取,及S1 和S2 的划分。选取分割点m的一个基本要求是由此导出集合S的一个线性分割,即S=S1 ∪S2 ,S1 ∩S2=Φ ,且S1 {x|x≤m};S2 {x|x>m}。容易看出,如果选取m=[max(S)+min(S)]/2,可以满足线性分割的要求。选取分割点后,再用O (n)时间即可将S划分成S1 ={x∈S|x≤m}和S2 ={x∈S|x>m}。然而,这样选取分割点m,有可能造成划分出的子集S1 和S2 的不平衡。例如在最坏情况下,|S1 |=1,|S2 |=n-1,由此产生的分治法在最坏情况下所需的计算时间T(n)应满足递归方程:

   T(n)=T(n-1)+O (n)

    它的解是T(n)=O (n2 )。这种效率降低的现象可以通过分治法中“平衡子问题”的方法加以解决。也就是说,我们可以通过适当选择分割点m,使S1 和S2 中有大致相等个数的点。自然地,我们会想到用S的n个点的坐标的中位数来作分割点。在选择算法 中介绍的选取中位数的线性时间算法使我们可以在O (n)时间内确定一个平衡的分割点m。

    至此,我们可以设计出一个求一维点集S中最接近点对的距离的算法CPAIR1如下。

function CPAIR1(S);
begin
  if |S|=2 then δ=|x[2]-x[1]| // x[1..n]存放的是S中n个点的坐标
           else if (|S|=1) 
                   then δ:=∞
                   else begin
                          m:=S中各点的坐标值的中位数;
                          构造S1和S2,使S1={x∈S|x≤m},S2={x∈S|x>m};
                          δ1:=CPAIRI(S1);
                          δ2:=CPAIRI(S2);
                           p:=max(S1);
                           q:=min(S2);
                          δ:=min(δ1,δ2,q-p);
                        end;
  return(δ);
end;

    由以上的分析可知,该算法的分割步骤和合并步骤总共耗时O (n)。因此,算法耗费的计算时间T(n)满足递归方程:

    解此递归方程可得T (n )=O (n logn )。

    这个算法看上去比用排序加扫描的算法复杂,然而这个算法可以向二维推广。

    下面我们来考虑二维的情形。此时S中的点为平面上的点,它们都有2个坐标值x和y。为了将平面上点集S线性分割为大小大致相等的2个子集S1 和S2 ,我们选取一垂直线l:x=m来作为分割直线。其中m为S中各点x坐标的中位数。由此将S分割为S1 ={p∈S|px ≤m}和S2 ={p∈S|px >m}。从而使S1 和S2 分别位于直线l的左侧和右侧,且S=S1 ∪S2 。由于m是S中各点x坐标值的中位数,因此S1 和S2 中的点数大致相等。

    递归地在S1 和S2 上解最接近点对问题,我们分别得到S1 和S2 中的最小距离δ 1δ 2 。现设δ =min(δ 1 ,δ 1 )。若S的最接近点对(p,q)之间的距离d(p,q)<δ 则p和q必分属于S1 和S2 。不妨设p∈S1 ,q∈S2 。那么p和q距直线l的距离均小于δ 。因此,我们若用P1 和P2 分别表示直线l的左边和右边的宽为δ 的2个垂直长条,则p∈S1 ,q∈S2 ,如图2所示。

图2 距直线l的距离小于δ 的所有点

    在一维的情形,距分割点距离为δ 的2个区间(m-δ ,m](m,m+δ ]中最多各有S中一个点。因而这2点成为唯一的末检查过的最接近点对候选者。二维的情形则要复杂些,此时,P1 中所有点与P2 中所有点构成的点对均为最接近点对的候选者。在最坏情况下有n2 /4对这样的候选者。但是P1 和P2 中的点具有以下的稀疏性质,它使我们不必检查所有这n2 /4对候选者。考虑P1 中任意一点p,它若与P2 中的点q构成最接近点对的候选者,则必有d(p,q)<δ 。满足这个条件的P2 中的点有多少个呢?容易看出这样的点一定落在一个δ ×2δ 的矩形R中,如图3所示。

图3 包含点q的δ ×2δ 的矩形R

δ 的意义可知P2 中任何2个S中的点的距离都不小于δ 。由此可以推出矩形R中最多只有6个S中的点。事实上,我们可以将矩形R的长为2δ 的边3等分,将它的长为δ 的边2等分,由此导出6个(δ /2)×(2δ/3) 的矩形。如图4(a)所示。

图4 矩形R中点的稀疏性

    若矩形R中有多于6个S中的点,则由鸽舍原理易知至少有一个δ ×2δ 的小矩形中有2个以上S中的点。设u,v是这样2个点,它们位于同一小矩形中,则

    因此d(u,v)≤5 δ /6< δ 。这与δ 的意义相矛盾。也就是说矩形R中最多只有6个S中的点。图4(b)是矩形R中含有S中的6个点的极端情形。由于这种稀疏性质,对于P1 中任一点p,P2 中最多只有6个点与它构成最接近点对的候选者。因此,在分治法的合并步骤中,我们最多只需要检查6×n/2=3n对候选者,而不是n2 /4对候选者。这是否就意味着我们可以在O (n)时间内完成分治法的合并步骤呢?现在还不能作出这个结论,因为我们只知道对于P1 中每个S1 中的点p最多只需要检查P2 中的6个点,但是我们并不确切地知道要检查哪6个点。为了解决这个问题,我们可以将p和P2 中所有S2 的点投影到垂直线l上。由于能与p点一起构成最接近点对候选者的S2 中点一定在矩形R中,所以它们在直线l上的投影点距p在l上投影点的距离小于δ 。由上面的分析可知,这种投影点最多只有6个。因此,若将P1 和P2 中所有S的点按其y坐标排好序,则对P1 中所有点p,对排好序的点列作一次扫描,就可以找出所有最接近点对的候选者,对P1 中每一点最多只要检查P2 中排好序的相继6个点。

    至此,我们可以给出用分治法求二维最接近点对的算法CPAIR2如下:

function CPAIR2(S);
begin
  if |S|=2 then δ:=S中这2点的距离
     else if |S|=0 
           then δ:=∞
           else begin
                 1.  m:=S中各点x坐标值的中位数;
                     构造S1和S2,使S1={p∈S|px≤m}和S2={p∈S|px>m}
                 2.  δ1:=CPAIR2(S1);δ2:=CPAIR2(S2);
                 3.  δm:=min(δ1,δ2);
                 4.  设P1是S1中距垂直分割线l的距离在δm之内的所有点组成的集合,
                     P2是S2中距分割线l的距离在δm之内所有点组成的集合。将P1和
                     P2中的点依其y坐标值从小到大排序,并设P1*和P2*是相应的已排
                     好序的点列;
                 5.  通过扫描P1*以及对于P1*中每个点检查P2*中与其距离在δm之内的
                     所有点(最多6个)可以完成合并。当P1*中的扫描指针逐次向上移动
                     时,P2*中的扫描指针可在宽为2δm的一个区间内移动。设δl是按
                     这种扫描方式找到的点对间的最小距离;
                 6.  δ=min(δm,δl);
               end;
  return(δ);
end;

    下面我们来分析一下算法CPAIR2的计算复杂性。设对于n个点的平面点集S,算法耗时T(n)。算法的第1步和第5步用了O (n)时间,第3步和第6步用了常数时间,第2步用了2T(n/2)时间。若在每次执行第4步时进行排序,则在最坏情况下第4步要用O (n logn )时间。这不符合我们的要求。因此,在这里我们要作一个技术上的处理。我们采用设计算法时常用的预排序技术,即在使用分治法之前,预先将S中n个点依其y坐标值排好序,设排好序的点列为P* 。在执行分治法的第4步时,只要对P* 作一次线性扫描,即可抽取出我们所需要的排好序的点列P1* 和P2* 。然后,在第5步中再对P1* 作一次线性扫描,即可求得δ l 因此,第4步和第5步的两遍扫描合在一起只要用O (n)时间。这样一来,经过预排序处理后的算法CPAIR2所需的计算时间T(n)满足递归方程:

    显而易见T(n)=O (n logn ),预排序所需的计算时间为O (n 1ogn )。因此,整个算法所需的计算时间为O (n logn )。在渐近的意义下,此算法已是最优的了。

 

个人认为算法其实并不难,只是作者的文字表达功力和严谨的思维和一步步深入解决问题的能力相当值得学习

分享到:
评论

相关推荐

    最接近点对问题算法用以解决最接近点对的算法

    最接近点对问题在计算机科学领域,特别是在几何算法和数据结构中占据着重要地位。它是一个寻找二维或高维空间中两个点之间最小距离的问题。这个问题有多种算法解决方案,每种都有其特定的效率和适用场景。以下是关于...

    算法分析与设计——最接近点对问题 (一、二维)详细解答,附完整代码!! 看这一篇就够啦!!!

    掌握分治法解平面最接近点对算法设计思想、算法设计过程及程序编码实现。 采用分治法解最接近点对问题。请回答以下问题: 1)一维情形下如何用线性时间完成合并步骤? 2)二维情形下递归求解递归出口如何设置? 3)二维...

    最接近点算法

    最接近点算法是一种在计算机科学和数学中广泛使用的算法,主要应用于几何计算、数据挖掘、图形学和机器学习等领域。它的目标是找到一组点集中距离最近的两个点对。在这个特殊的案例中,算法是通过MFC(Microsoft ...

    算法 最接近点对问题一维

    在计算机科学和算法设计中,"最接近点对问题"是一个经典的几何问题,它寻找一组点集中距离最近的两个点。在这个场景下,我们关注的是在一维空间中的点对问题,也就是只考虑沿一条直线分布的点。这个问题相对简单,但...

    求平面上最接近点对算法实现

    在计算机科学中,"求平面上最接近点对算法实现"是一个经典的几何问题,它涉及到数据结构、算法设计以及计算几何。这个问题的目标是找到给定的一组二维坐标点中,距离最近的两个点对。这样的算法在多个领域都有应用,...

    平面点集最接近点对源码

    在计算机科学领域,尤其是算法分析与设计中,解决“平面点集最接近点对”问题是一项重要的挑战。这个问题要求在给定的二维平面上的一组点中,找到距离最近的两个点。这个问题广泛应用于各种场景,如数据挖掘、图形学...

    分治法实现最接近点对问题的三维推广算法

    ### 分治法实现最接近点对问题的三维推广算法 #### 概述 最接近点对问题是指在一组给定点集中找到距离最近的两点。这是一个经典的计算机几何问题,在空中交通控制、模式识别、图像处理等领域有着广泛的应用。利用...

    用分治算法解平面最接近点对问题

    通过以上分析,我们可以看到,分治算法为解决平面最接近点对问题提供了高效的方法,避免了对所有点对的直接检查,尤其适用于大数据量的情况。而C++代码实现则将算法逻辑转化为可执行的程序,方便进行实际应用。

    算法分析与设计-最接近点对问题的java实现

    算法分析与设计-最接近点对问题的java实现 用java实现的最接近点对问题,包括一维情况和二维情况!

    分治法 解 平面最接近点对问题

    分治法是一种重要的算法设计策略,它将一个大问题分解为若干个规模较...总的来说,“分治法解平面最接近点对问题”是算法设计和数据结构应用的经典案例,通过理解和掌握这种方法,可以有效地解决复杂度较高的计算问题。

    java最接近点对问题

    这里我们将详细探讨如何利用分治算法来解决Java中的最接近点对问题。 首先,我们需要理解分治算法的基本思想。分治法是一种将大问题分解为若干个小问题,分别解决后再合并结果的策略。在处理最接近点对问题时,我们...

    一维最接近点对问题c#实现

    总的来说,这个C#程序结合了算法设计、数据结构、用户交互和面向对象编程等多个方面的知识,提供了一个实用的工具来解决一维最接近点对问题。它不仅锻炼了开发者解决问题的能力,也为学习者提供了一个很好的实践案例...

    最接近点对问题.二维

    最接近点对问题在计算机科学领域,特别是在几何算法和数据结构中,是一个经典的问题。它涉及到寻找一组点集中两个点之间的最短距离。在二维空间中,这个问题相对简单,但实际实现时可能会遇到一些挑战,尤其是在处理...

    二维最接近点对 (分治法)

    二维最接近点对问题是一个经典的计算几何问题,其目标是在给定的一组二维平面上的点集中找到距离最近的两点对。这个问题在图形学、数据挖掘、地理信息系统等领域有着广泛的应用。分治法是一种高效的算法设计策略,它...

    离散数学及其应用---最近点对算法C++实现

    离散数学作为计算机科学的基础,其在算法设计和分析中占据着重要地位。最近点对问题(Closest Pair Problem)是...在实际应用中,这种算法可应用于地理信息系统、图像处理、机器学习等多个领域,寻找最接近的数据点对。

    平面最近点对问题分治算法解答,C++实现

    平面最近点对问题分治算法解答,C++实现,代码整洁规范。

    最接近点对问题LPP

    1. **算法原理.doc** - 这可能包含对最接近点对问题的详细解释,包括问题背景、算法描述、复杂度分析等。文档可能会详细讲解分治法的具体步骤,如何进行点集的分割,以及如何结合左右子集的结果找到跨分界线的最近点...

    分治算法第3节_最接近点对.pptm

    分治算法第3节_最接近点对.pptm

Global site tag (gtag.js) - Google Analytics