我可以计算距离严格小于 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 最近让我很感兴趣。更具体地说,分治算法。
这种递归算法要求我将一组点分成两个块,a
和 b
,并为每个块计算最接近的点对,然后计算块之间最接近的点对并返回最小值这 3 个数量。
计算块之间最近点的算法仅通过迭代至多 7 个点来工作,这些点距 a
中的最后一个点(整个集合的平均元素)至多为 min(a, b)
。
这两张图片更好地代表了这个问题。 min(a, b) = Delta
.
我知道,如果我要在两侧的 l
线上有 2 个点,a
和 b
,我需要在中间的条带上最多比较 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)。
1234563Y
轴。 (注意:分离“左”点和“右”点是必须从-?
开始的原因)
现在从该起始位置继续向上并计算与当前左侧点位于+?
之前的所有点的距离。
在第 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
的含义。实际上,您不会检查4
或7
或任何固定数量的点,而是沿着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 的最近分割点对吗的主要内容,如果未能解决你的问题,请参考以下文章