You are on page 1of 3

import random

import time
import math

def generate_random_points(n):
return [(random.uniform(-10, 10), random.uniform(-10, 10)) for _ in
range(n)]

def euclidean_distance(p1, p2):


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

def closest_pair(points):
min_distance = float('inf')
closest_points = (None, 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_points = (points[i], points[j])

return closest_points, min_distance

def measure_time(n):
points = generate_random_points(n)
start_time = time.time()
result = closest_pair(points)
end_time = time.time()
elapsed_time = end_time - start_time
return n, result, elapsed_time

if __name__ == "__main__":
for n in [10, 100, 1000, 10000, 100000]:
print(measure_time(n))

El tiempo de ejecución aumentará cuadráticamente con el número


de puntos debido a la complejidad O (n^2) del algoritmo. Por lo
tanto, para n=100000, el tiempo de ejecución podría ser
significativamente más largo en comparación con los valores más
pequeños de n.
En este modo se emplea fuerza bruta por lo que también se
aumento la complejidad del algoritomo.

Empleando Divide y venceras :

import math
import random

def euclidean_distance(p1, p2):


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

def closest_pair_recursive(points_sorted_by_x, points_sorted_by_y):


if len(points_sorted_by_x) <= 3:
return min([euclidean_distance(points_sorted_by_x[i],
points_sorted_by_x[j])
for i in range(len(points_sorted_by_x))
for j in range(i+1, len(points_sorted_by_x))])

mid = len(points_sorted_by_x) // 2

left_half_x = points_sorted_by_x[:mid]
right_half_x = points_sorted_by_x[mid:]

distance_left = closest_pair_recursive(left_half_x, points_sorted_by_y)

distance_right = closest_pair_recursive(right_half_x,
points_sorted_by_y)

d = min(distance_left, distance_right)

strip = [point for point in points_sorted_by_y if abs(point[0] -


points_sorted_by_x[mid][0]) < d]
min_strip_distance = float('inf')
for i in range(len(strip)):
for j in range(i+1, len(strip)):
if strip[j][1] - strip[i][1] < d and
euclidean_distance(strip[i], strip[j]) < min_strip_distance:
min_strip_distance = euclidean_distance(strip[i], strip[j])

return min(d, min_strip_distance)

def closest_pair(points):
points_sorted_by_x = sorted(points, key=lambda p: p[0])
points_sorted_by_y = sorted(points, key=lambda p: p[1])
return closest_pair_recursive(points_sorted_by_x, points_sorted_by_y)

# Test
points = [(random.uniform(-10, 10), random.uniform(-10, 10)) for _ in
range(100)]
print(closest_pair(points))

Con el teorema del maestro


a=2 (número de subproblemas)
b=2 (factor por el que se divide el tamaño del problema)
f(n)= n (costo del trabajo realizado fuera de las llamadas recursivas)

Por lo tanto
T(n)= n log n

N Tiempo
10 0.0001
100 0.001
1000 0.02
10000 0.25
100000 3.5

You might also like