无法理解 Closest-Pair 分治算法

Posted

技术标签:

【中文标题】无法理解 Closest-Pair 分治算法【英文标题】:Trouble understanding Closest-Pair divide and conquer algorithm 【发布时间】:2020-07-20 04:49:02 【问题描述】:

我是编码新手,今天我完成了二维空间中最近对问题的简单解决方案。 (2个for循环)

但是我放弃了寻找任何可以在 O(n log n) 中完成的解决方案。即使研究了它,我仍然不明白这怎么能比琐碎的方法更快。

我的理解: -> 首先,我们将数组分成两半,并仅考虑 X 坐标对所有内容进行排序。这可以在 n log n 中完成。

接下来是递归调用,在每一半中“找到距离最短的两个点”。 但是这是如何在 O(n^2) 以下完成的呢? 据我了解,如果不检查每一个点,就不可能找到 N/2 个点之间的最短距离。

有一维的解决方案对我来说绝对有意义。排序后我们知道,两个不相邻的点之间的距离不能小于至少两个相邻点的距离。然而,对于二维空间,情况并非如此,因为我们有一个额外的 Y 坐标,这可能导致在 X 轴上不相邻的两点之间的距离最小。

【问题讨论】:

例如,这个问题与快速排序有何不同?你有T(n) = 2 T(n/2) + O(n) 重复,这给了你时间限制。在进行任何递归调用之前,您只对点进行一次排序。 是的,但是是什么让递归调用比遍历数组更便宜?据我了解,我仍然必须检查每个点及其距离,而无需使用循环。如果我只检查具有相邻 X 坐标的点(可以完成 O(n)),我可能会错过非相邻(关于 X 轴)点之间可能存在的最小距离。 我建议你看一下算法的描述。例如,参见 sec。 33.4 在 T.H.Cormen、C.E.Leiserson、R.L.Rivest、C.Stein 中找到最近的一对点算法简介. 【参考方案1】:

首先,听从用户@Evg 的建议——这个答案不能替代对算法的全面描述和数学上严谨的分析。

但是,这里有一些想法可以帮助您开始直觉:

    (递归结构) 问题说明:

    接下来是递归调用,在每一半中“找到距离最短的两个点”。但是这是如何在 O(n^2) 以下完成的呢?据我了解,如果不检查每一个点,就不可能找到 N/2 个点之间的最短距离。

    然而,递归不会在级别 1 停止 - 为了论证的缘故,假设某些 O(n log n) 算法有效。应用该算法在 N/2 点之间找到最接近的对需要 O(N/2 log N/2) - 而不是 O((N/2)^2)

    (在一半中找到最接近的一对的后果) 如果您在点集的“左”半部分中找到了最近的一对(p, q),则该对的距离将上限设置为减半线周围走廊的宽度,从该走廊的距离更近的一对(r, s)r从左边可以画出右半边的s。如果到目前为止找到的最近距离是“小”,它会显着减小候选集的大小。由于这些点已按其x 坐标排序,因此该算法可以有效地利用信息。 所述走廊可能仍然覆盖整个N 点集,但如果覆盖,它会提供点集的几何信息:每一半的点将基本上沿垂直线对齐。可以通过算法利用此信息 - 最简单的方法是再次执行算法,但沿y 坐标排序并将水平线设置的点减半。请注意,以恒定次数执行任何算法不会改变由O(.) 表示法表示的渐近运行时间。

    (找到一对接近的一对,每半场都有一个点) 考虑检查一对点(r, s),每半场一个点。众所周知,它们的xy 坐标的差异分别不能超过目前发现的最小距离d。从递归可知,没有点r', s'(左侧为r',右侧为s')更接近r, s,分别比d更接近。所以考虑到一些r,另一半不可能有“很多”候选人。 想象一个半径为d 的圆围绕r 绘制。任何距离另一半比d 更近的点s 必须位于该圆内。让他们中的一些 - 然而,每对之间的最小距离仍然至少是d。可以在半径为d 的圆内分布的最大点数使得每对之间的距离至少为d 是 7 - 考虑一个边长为 d 的正六边形,其中心与圆的中心。 因此,在递归之后,最多需要检查左半部分的每个r 与另一半的最大点数相同,这使得递归后的算法部分在O(N) 中运行。 请注意,为给定的 r 找到配对候选者是一种高效的操作 - 来自两半的点已按相同的标准排序。

【讨论】:

以上是关于无法理解 Closest-Pair 分治算法的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法-进阶(十九)分治

分治FFT

算法有关点分治的一些理解与看法

2.3.1 分治法

关于分治算法的个人理解

动态规划和分治法,贪心算法以及递归的再一次深刻理解和体会