我可以计算距离严格小于 delta 的最近分割点对吗

Posted

技术标签:

【中文标题】我可以计算距离严格小于 delta 的最近分割点对吗【英文标题】:Can I compute closest split pair of points where distance is strictly less than delta 【发布时间】:2019-06-02 10:41:11 【问题描述】:

最近的Pair of Points Problem 最近让我很感兴趣。更具体地说,分治算法。

这种递归算法要求我将一组点分成两个块,ab,并为每个块计算最接近的点对,然后计算块之间最接近的点对并返回最小值这 3 个数量。

计算块之间最近点的算法仅通过迭代至多 7 个点来工作,这些点距 a 中的最后一个点(整个集合的平均元素)至多为 min(a, b)

这两张图片更好地代表了这个问题。 min(a, b) = Delta.

我知道,如果我要在两侧的 l 线上有 2 个点,ab,我需要在中间的条带上最多比较 7 个点。

我想知道的是,如果我构造中间带的点严格小于 Delta 远离l,我不能只比较接下来的 4 个点,而不是 7 个,因为我只能适合 2 个点在l 的每一侧,距离l 的距离小于Delta 和距离彼此的Delta?

编辑: 我也为 cs stackexchange 上的一个非常相似的问题开始了赏金,我们在那里提出了一个非常有趣的讨论。所以我链接它here。我们还开始了一次非常有见地的聊天here。

【问题讨论】:

“我只能在 l Delta 的每一侧放置 2 个点彼此远离”。事实上,我们可以拟合 3 个点。 4 次比较就足够了。但是,我还没有找到一个不乱的证明。 顺便说一句,很好的观察和很好的问题。刚刚都投了赞成票。 【参考方案1】:

注意:此答案已根据与 @Danilo Souza Morães 和 @burnabyRails(accepted answer 的作者)就 Danilo 在 CS 网站上提出的类似问题的广泛讨论进行更新,以供将来参考.原始答案的主要问题是我假设这里使用/讨论了一些不同的算法。由于最初的答案为达尼洛提供了一些重要的见解,因此它在最后被保留了下来。此外,如果您要阅读 Danilo 在他的回答中提到的discussion,请务必先阅读此处的介绍,以更好地理解我的意思。添加的前言讨论了相关算法的不同版本。

简介

该算法基于两个主要思想:

    典型的递归分治法 事实上,如果您已经知道左右区域的最佳距离,您可以在O(N) 时间执行“合并”步骤,因为您可以证明您可以在O(1) 时间对每个点进行检查.

尽管如此,在实践中仍有多种方法可以实现相同的基本思想,尤其是组合步骤。主要区别在于:

    您是否会以不同的方式独立处理“左”点和“右”点? 您是针对每个点进行固定数量的检查,还是先过滤候选者,然后只对过滤后的候选者进行距离检查?请注意,如果您可以确保在摊销 O(1) 中完成过滤,您可以在不破坏 O(N*log(N)) 时间的情况下进行一些过滤。换句话说,如果您知道优秀候选人的数量有一个很大的上限,您就不必准确检查候选人的数量。

CLRS Introduction to Algorithms 中算法的经典描述清楚地回答了问题 #1,因为您将“左”和“右”点混合在一起并共同对待它们。至于#2,答案不太清楚(对我来说),但它可能意味着检查一些固定数量的点。这似乎是达尼洛提出问题时想到的版本。

我想到的算法在这两点上都不同:它向上通过“左”点,并对照所有过滤的“右”候选点检查它们。显然,在我写答案时以及在聊天中进行初步讨论时,我并没有意识到这种差异。

“我的”算法

这是我想到的算法的草图。

    开始步骤很常见:我们已经处理了“左”和“右”点,并且知道目前为止最好的?,我们将它们沿着Y 轴排序。我们还过滤掉了所有不在±? 条带中的点。

    外循环是我们通过“左”点向上。现在假设我们处理一个,我们称之为“左点”。此外,在必要时,我们会半独立地迭代移动“起始位置”的“正确”点(参见步骤 #2)。

    1234563 Y 轴。 (注意:分离“左”点和“右”点是必须从-? 开始的原因)

    现在从该起始位置继续向上并计算与当前左侧点位于+? 之前的所有点的距离。

在第 2 步和第 3 步中完成的过滤使其“依赖于数据”。此实现中的权衡是,您以更多Y-checks 为代价进行更少的距离检查。此外,代码可能更复杂。

为什么这种组合算法适用于O(N)?出于同样的原因,在矩形?x2? 中可以容纳多少个点有一个固定界限(即O(1)),这样每两个点之间的距离至少为?。这意味着将在第 3 步进行O(1) 检查。实际上,该算法检查的所有距离都将由 CLRS 版本检查,并且根据数据,可能还会检查更多距离。

第 2 步的摊销成本也是 O(1),因为第 2 步在整个外循环上的总成本是 O(n):您显然不能将起始位置向上移动的次数超过总共“正确的点”。

改进的 CLRS 算法

即使在算法的 CLRS 版本中,您也可以轻松地对 #2 做出不同的决定。关键步骤的描述说:

    对于数组Y′ 中的每个点p,算法会尝试在Y′ 中找到位于δ 单位p 内的点。正如我们很快将看到的,只需要考虑Y′ 中紧随p 的7 个点。该算法计算从 p 到每个 7 点的距离,并跟踪在 Y′ 中的所有点对中找到的最近对距离 δ′

很容易修改为不检查7点,而是首先检查Y的差异是否小于?。显然,您仍然保证需要检查不超过7 点。同样的权衡是你做的距离检查更少,但做一些Y-difference 检查。根据您的数据和硬件上不同操作的相对性能,这可能是一个好坏的权衡。

其他一些重要的想法

    如果您不需要找到所有距离最小的对,您可以在过滤时安全地使用<?`` instead of

    在使用浮点数表示的真实硬件世界中,= 的概念并不那么清楚。通常你需要检查类似abs(a - b) < έ 的东西。

    我的反例背后的想法(针对不同的算法):您不必将所有点都放在边缘上。边为? 的等边三角形可以放入大小为?-έ 的正方形中(即<? 的另一种说法)


原答案

我认为您没有正确理解该算法中常量7 的含义。实际上,您不会检查47 或任何固定数量的点,而是沿着Y 轴向上(或向下)并检查落入相应矩形的点。很容易可能只有0 这样的点。对于算法在承诺的O(n*log(n)) 时间内运行真正重要的是,在该步骤检查的点数有一个固定上限。只要你能证明它,任何 constant 上限都可以工作。换句话说,重要的是该步骤是O(n),而不是特定的常数。 7 只是一个比较容易证明的,仅此而已。

我相信7 的实际原因是,在真实硬件上,您无法精确计算浮点数据类型中的距离,您肯定会遇到一些舍入误差。这就是为什么使用< 而不是<= 并不实用。

最后我不认为4 是一个正确的界限,假设你可以可靠地做到<。假设? = 1。让“左”点为(-0.0001; 0),因此“右”< 矩形为0 <= x < 1-1 < y < 1。考虑以下 5 个点(想法是:几乎在角落的 4 个点正好适合矩形< ? 和它们之间的距离> ?,第 5 个在矩形的中心):

P1 = (0.001; 0.999) P2 = (0.999; 0.93) P3 = (0.001; -0.999) P4 = (0.999; -0.93) P5 = (0.5; 0)

请注意,这 5 个点之间的距离应大于?,其中一些距离“左”点可能小于?。这就是我们首先检查它们的原因。

距离P1-P2(和对称的P3-P4)是

sqrt(0.998^2 + 0.069^2) = sqrt(0.996004 + 0.004761) = sqrt(1.000765) > 1

距离P1-P5(和对称的P3-P5)是

sqrt(0.499^2 + 0.999^2) = sqrt(0.249001 + 0.998001) = sqrt(1.247002) > 1

距离P2-P5(和对称的P4-P5)是

sqrt(0.499^2 + 0.93^2) = sqrt(0.249001 + 0.8649) = sqrt(1.113901) > 1

因此,您可以将5 点放入这样一个明显大于4< 矩形中。

【讨论】:

我不确定你是如何得出我不懂算法的结论的。我并不是说 4 次比较会呈现渐近更快的算法。我只是想问一下 wikipedia 中给出的常数 7 是否可以缩减到 4,因为这是适合边长小于 ? 的矩形的最大点数。我在问题中提出了所有这些事实,以表明我完全理解算法的工作原理,但我正在寻找一种方法来证明我提出的这个小改进确实有效。 @DaniloSouzaMorães,好吧,我可能误解了你,抱歉。我仍然不喜欢你称之为“改进”的事实,因为它并没有真正影响任何事情。无论如何,您是否看到我的反例并在我的答案末尾有 5 分的问题?恕我直言,它显然反驳了将其缩减到 4 的整个想法。 您的答案正是我想要的。我以前没有接受它,因为我花了相当长的时间研究和绘制它。我对我提出的另一个问题也得到了很好的回答,所以我只是在那里发表了一些评论,然后才转到 SO 接受你的 你是对的,这不是一种改进,因为它不起作用。我的假设是我最多可以拟合 2 个点,彼此相距 δ,与 l 相距小于 δ。我认为是这种情况,因为如果我要在边 δ 的正方形的角上放置 3 个点,然后开始将一个边缘上的 2 个点移动到更靠近第 3 个点,那么第 3 个点将被强制移出正方形保持δ的最小距离。但事实并非如此,正如你用你的一组点所展示的那样。第三个点可以向边缘的中心移动,最终形成一个等边三角形。 @DaniloSouzaMorães,我不喜欢称其为“改进”,不是因为它是错误的,而是因为即使它是真的,它既不会影响算法的实际性能,也不会影响理论O(N*log(N)) 的边界。

以上是关于我可以计算距离严格小于 delta 的最近分割点对吗的主要内容,如果未能解决你的问题,请参考以下文章

luogu P1429 平面最近点对

平面最近点对(分治nlogn)

计算几何学习8

平面最近点对问题

使用曼哈顿距离的最近点对

POJ3608(旋转卡壳--求两凸包的最近点对距离)