分治算法最近点对代码

下面是一个使用分治算法解决最近点对问题(Closest Pair)的代码示例:

import math

def euclidean_distance(p1, p2):
    return math.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)

def brute_force(points):
    min_distance = float('inf')
    closest_pair = None

    for i in range(len(points)):
        for j in range(i+1, len(points)):
            distance = euclidean_distance(points[i], points[j])
            if distance < min_distance:
                min_distance = distance
                closest_pair = (points[i], points[j])

    return closest_pair

def closest_pair(points):
    if len(points) <= 3:
        return brute_force(points)

    mid = len(points) // 2
    mid_point = points[mid]

    left_points = points[:mid]
    right_points = points[mid:]

    left_closest = closest_pair(left_points)
    right_closest = closest_pair(right_points)

    if left_closest is None:
        closest = right_closest
    elif right_closest is None:
        closest = left_closest
    else:
        left_distance = euclidean_distance(left_closest[0], left_closest[1])
        right_distance = euclidean_distance(right_closest[0], right_closest[1])
        closest = left_closest if left_distance < right_distance else right_closest

    strip_closest = closest_in_strip(points, mid_point, closest)
    return strip_closest if strip_closest is not None else closest

def closest_in_strip(points, mid_point, closest):
    strip = []
    min_distance = euclidean_distance(closest[0], closest[1])

    for point in points:
        if abs(point[0] - mid_point[0]) < min_distance:
            strip.append(point)

    strip.sort(key=lambda p: p[1])

    for i in range(len(strip)):
        j = i + 1
        while j < len(strip) and (strip[j][1] - strip[i][1]) < min_distance:
            distance = euclidean_distance(strip[i], strip[j])
            if distance < min_distance:
                min_distance = distance
                closest = (strip[i], strip[j])
            j += 1

    return closest

# 示例用法
points = [(2, 3), (12, 30), (40, 50), (5, 1), (12, 10), (3, 4)]
closest = closest_pair(points)
print("Closest pair:", closest)

这段代码实现了分治算法来解决最近点对问题。首先,我们定义了计算欧几里得距离的函数 euclidean_distance。然后,我们使用朴素的暴力解法 brute_force 来处理点数较少的情况。

在主函数 closest_pair 中,我们采用分治的策略。首先,将点集按照 x 坐标进行排序,并找到中间点 mid_point。然后,将点集分为左右两部分,并递归地对左右子集进行求解。

接下来,我们通过比较左右子集的最近点对结果 left_closestright_closest 来确定最终的最近点对 closest。如果其中一个子集没有最近点对结果,我们选择另一个子集的结果作为最近点对。

最后,我们调用 closest_in_strip 函数来查找可能跨越分割线的最近点对。在 closest_in_strip 中,我们将横跨分割线的点集按照 y 坐标排序,并使用滑动窗口来寻找距离更近的点对。

在示例用法中,我们创建了一个包含 6 个点的列表,并调用 closest_pair 函数来找到最近点对。最终结果会被打印输出。

请注意,这只是一个简单的示例,用于说明最近点对问题的分治算法实现。在实际应用中,你可能需要根据具体情况进行适当的调整和优化。

posted @ 2023-06-04 15:00  拓源技术  阅读(57)  评论(0编辑  收藏  举报