我正在尝试理解最接近点对算法。我了解如何将集合分成两半,但我不太明白如何通过递归计算最接近的点对。我了解递归,但不知道如何通过递归计算最接近的点对。如果给你这些点:(1,2)(1,11)(7,8),那么递归应该如何工作呢?
算法的基本思想是这样的。你有一组点P,你想找到P中距离最短的两个点。一个简单的暴力方法是遍历P中的每一对点,计算它们之间的距离,然后选择距离最短的一对。这是一个O(n²)的算法。但是,你所说的算法可以更好地解决这个问题。首先,按照其中一个坐标(例如x坐标)对所有点进行排序。现在,你的集合P实际上是一个按其x坐标排序的点列表。该算法现在将其输入设置为一组有序的点,而不是一组点。我们称这个算法为ClosestPair(L),其中L是作为参数给出的点列表。ClosestPair(L)的递归实现如下:1.将列表L在中间分成Lleft和Lright两部分。2.递归解决ClosestPair(Lleft)和ClosestPair(Lright)。让相应的最短距离分别为δleft和δright。3.现在我们知道原始集合(由L表示)中的最短距离要么是两个δ中的一个,要么是Lleft中的一个点和Lright中的一个点之间的距离。4.因此,我们仍然需要检查左右子分区中是否存在更短的距离。这个技巧是,因为我们知道距离必须小于δleft和δright,所以只需要考虑从分割线(你用来分割原始列表L的x坐标)不超过min(δleft,δright)的点即可。这种优化使得该过程比暴力方法更快,实际上是O(n log n)。
如果你指的是这个算法,你需要按照以下步骤进行: 对点进行排序:(1,2) (1,11) (7,8) 构建两个子集:(1,2) (1,11) 和 (7,8) 分别在 (1,2) (1,11) 和 (7,8) 上运行算法 <= 这里涉及到递归。结果为 dLmin = 9 和 dRmin = infinity(右侧没有第二个点) dLRmin = sqrt(45) result = min(dLmin, dRmin, dLRmin) = sqrt(45) 递归包括与上述相同的步骤。例如,使用 (1,2) 和 (1,11) 进行调用: 排序点:(1,2) (1,11) 构建两个子集:(1,2) 和 (1,11) 分别在 (1,2) 和 (1,11) 上运行算法 <= 再次递归调用。结果是 dLmin = 无穷大,dRmin = 无穷大 dLRmin = 9 结果 = min(dLmin, dRmin, dLRmin) = 9