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

时间:2019-01-07 18:35:49

标签: algorithm divide-and-conquer clrs

最近的Pair of Points Problem最近吸引了我。更具体地说,是分治法。

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

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

这两张照片代表了更好的问题。 min(a, b) = Delta

enter image description here

我了解到,如果我在la两边的b线上有2个点,那么我最多需要在中间比较7个点剥离。

我想知道的是,如果我构建的中间条带的点距l的距离小于Delta,我不能仅比较接下来的4点而不是7点,因为我只能拟合l的每一侧有2个点,距离l的Delta小于彼此的Delta?

编辑: 我也开始悬赏cs stackexchange上的一个非常类似的问题,在那里我们进行了非常有趣的讨论。因此,我将其链接为here。我们还开始了非常有见地的聊天here

1 个答案:

答案 0 :(得分:1)

注意:该答案已更新,以供将来参考,其依据是与accepted answer的作者@Danilo SouzaMorães和@burnabyRails进行的广泛讨论。 CS网站。原始答案的主要问题是,我假设此处使用/讨论了一些不同的算法。由于原始答案为Danilo提供了一些重要的见解,因此保留了原样。另外,如果您要阅读Danilo在回答中提到的discussion,请务必先阅读此处的介绍,以更好地理解我的意思。添加的序言部分讨论了所讨论算法的不同版本。

简介

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

  1. 典型的递归分治法
  2. 如果您已经知道左右两个区域的最佳距离,就可以在O(N)的时间内完成“组合”步骤,因为您可以证明可以对{{ 1}}时间。

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

  1. 您是否独立对待“左”和“右”点并且可能以不同的方式对待?
  2. 对于每个点,您都进行固定数量的检查,还是先过滤候选对象,然后仅对过滤后的候选对象进行距离检查?请注意,如果可以确保以摊销的O(1)完成过滤,则可以进行一些过滤而不会浪费O(N*log(N))时间。换句话说,如果您知道优秀候选人的人数上限很强,则不必精确检查该候选人的人数。

CLRS Introduction to Algorithms中算法的经典描述清楚地回答了问题1,因为您混合了“左”点和“右”点并对其进行了共同处理。至于#2,答案(对我而言)不太清楚,但可能意味着检查一些固定点数。这似乎是Danilo想到的那个版本。

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

“我的”算法

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

  1. 开始的步骤很常见:我们已经处理了“左”和“右”点,并知道最好的O(1)沙发,并沿轴对它们进行了排序。我们还过滤掉了Y条中不存在的所有点。

  2. 外部循环是,我们经过“左”点。现在假设我们处理一个,我们称其为“左点”。此外,我们在必要时半独立地遍历“正确”的点,以移动“起始位置”(请参阅​​步骤2)。

  3. 对于每个左点,请从右点的最后一个起始位置上移,然后递增起始位置,直到我们到达±(或更确切地说)与根据{{​​1}}轴的左点。 (注意:“左”点和“右”点之间的分隔使得必须从-开始)

  4. 现在从该起始位置继续向上,并计算到Y之前所有点与当前左点的距离。

在步骤#2和#3中进行的过滤使它“与数据相关”。在此实现中的权衡是,您进行的距离检查更少,但需要进行更多的-检查。此外,代码的争论也更复杂。

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

步骤2的摊销成本也为,因为整个外部循环中步骤2的总成本为O(1):您显然无法将起始位置进一步提高总共比“正确点”还多。

修改后的CLRS算法

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

  
      
  1. 对于数组O(1)中的每个点O(n),该算法尝试在p的{​​{1}}单位内的Y′中查找点。正如我们将很快看到的,仅需要考虑Y′之后的δ中的7个点。该算法计算从p到每个p点的距离,并跟踪在Y′的所有点对中找到的最接近对距离p
  2.   

很容易对其进行修改,以不检查7点,而是先检查δ′的差是否小于Y′。显然,您仍然可以保证检查的点数不超过7。再次需要权衡的是,您进行的距离检查较少,但进行了一些Y差异检查。取决于您的数据和硬件上不同操作的相对性能,这可能是一个好选择或一个坏选择。

其他一些重要想法

  1. 如果不需要查找所有具有最小距离的对,则可以在过滤时安全地使用 <=`

  2. 在具有浮点数表示形式的实际硬件世界中,7的概念尚不清楚。通常,无论如何,您都需要检查类似Y的内容。

  3. 我的反例背后的想法(针对另一种算法):您不必将所有点都放在边缘。侧面为<`` instead of的等边三角形可以拟合为大小为=的正方形(这是表示abs(a - b) < έ的另一种方式)


原始答案

我认为您没有正确理解该算法中该常数的含义。实际上,您不会检查<或任何固定数量的点,而是沿着7轴上(或下)并检查落入相应矩形中的点。很容易就有4这样的观点。对于算法在承诺的7时间内起作用而言,真正重要的是,在该步骤检查的点数上有一个固定上限。只要您能证明,任何恒定上限都将起作用。换句话说,重要的是该步骤是Y,而不是特定的常数。 0只是相对容易证明的一个而已。

我相信O(n*log(n))的实际原因是,在实际的硬件上,您无法对浮点数据类型中的距离进行精确的计算,因此一定会产生一些舍入误差。这就是为什么使用O(n)代替7并不实际的原因。

最后,假设您可以可靠地执行7,那么我不认为<是正确的界限。假设<=。假设“左”点为4,因此它的“右” <矩形为 = 1(-0.0001; 0)。考虑以下5个点(想法是:在拐角处几乎有4个点正好适合矩形<及其之间的距离0 <= x < 1,第5个点位于矩形的中心):

  • -1 < y < 1 = <
  • > = P1
  • (0.001; 0.999) = P2
  • (0.999; 0.93) = P3
  • (0.001; -0.999) = P4

请注意,这5个点之间的距离应大于(0.999; -0.93),其中一些距离“左”点可能小于P5。这就是为什么我们首先检查它们的原因。

距离(0.5; 0)(对称地)是

距离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