分治算法最近点对代码
下面是一个使用分治算法解决最近点对问题(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_closest
和 right_closest
来确定最终的最近点对 closest
。如果其中一个子集没有最近点对结果,我们选择另一个子集的结果作为最近点对。
最后,我们调用 closest_in_strip
函数来查找可能跨越分割线的最近点对。在 closest_in_strip
中,我们将横跨分割线的点集按照 y 坐标排序,并使用滑动窗口来寻找距离更近的点对。
在示例用法中,我们创建了一个包含 6 个点的列表,并调用 closest_pair
函数来找到最近点对。最终结果会被打印输出。
请注意,这只是一个简单的示例,用于说明最近点对问题的分治算法实现。在实际应用中,你可能需要根据具体情况进行适当的调整和优化。
本文来自博客园,作者:拓源技术,转载请注明原文链接:https://www.cnblogs.com/tuoyuanjishu/articles/17455700.html