diff --git a/doc/Informe.tex b/doc/Informe.tex index 6ba6bae..5d3124a 100644 --- a/doc/Informe.tex +++ b/doc/Informe.tex @@ -74,6 +74,7 @@ Xavier Canales \newpage \subsection{Divide and Conquer} +\lstinputlisting{pseudo/divide_and_conquer.txt} \newpage \section{Resultados} @@ -128,6 +129,10 @@ La siguiente tabla contiene los resultados de las pruebas de los 2 algoritmos me \newpage \subsection{Gráfico} +\begin{center} + \includegraphics[width=0.96\textwidth,height=0.96\textheight,keepaspectratio]{graph.png} +\end{center} + \newpage \section{Conclusiones} Para encontrar el par de puntos más cercano la ecuación es\\$ d = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2} $ diff --git a/doc/graph.png b/doc/graph.png new file mode 100644 index 0000000..2875d81 Binary files /dev/null and b/doc/graph.png differ diff --git a/doc/pseudo/brute_force.txt b/doc/pseudo/brute_force.txt index 66ba871..e03f6e8 100644 --- a/doc/pseudo/brute_force.txt +++ b/doc/pseudo/brute_force.txt @@ -1,24 +1,15 @@ -entrada: point_t = dirección de memoria de points - n = numero de - *minimum_dist = dirección de memoria para la distancia minima - -salida: - -point_t * funcion brute_force(inicio point_t *points, inicio n, inicio *minimum_dist){ - - point_t *closest_pair = espacio de memoria igual a el doble de point_t - inicio i - inicio j - inicio dist - - ciclo(inicio i = 0 hasta i < n con paso i++){ - ciclo (inicio j = i + 1 hasta j < n; j++){ - si((dist = funcion distance(punto i, punto j)) < *minimum_dist){ - *minimum_dist = dist - par_mas_cercano[0] = punto i - par_mas_cercano[1] = punto j +entrada: array: arreglo de n puntos; n: tamaño del arreglo +salida: los dos puntos mas cercanos con su distancia +funcion brute_force(points, n) { + para i = 0 mientras que i < n - 1 hacer + para j = i + 1 mientras que j < n hacer + si distance(points[i], points[j]) < distancia_minimo entonces + distancia_minimo = distancia + closest_pair[0] = points[i] + closest_pair[1] = points[j] } } - } -} \ No newline at end of file + } + return par_mas_cerca y distancia_minimo +fin funcion diff --git a/doc/pseudo/divide_and_conquer.txt b/doc/pseudo/divide_and_conquer.txt new file mode 100644 index 0000000..39f8a4d --- /dev/null +++ b/doc/pseudo/divide_and_conquer.txt @@ -0,0 +1,84 @@ +entrada: array: arreglo de n puntos; n: tamaño del arreglo +salida: los dos puntos mas cercanos con su distancia + +funcion divide_and_conquer_run(puntos_x, nx, puntos_y, ny) + si nx <= 4 then + par_mas_cerca2 = brute_force(puntos_x, nx, d) + par_mas_cerca[0] = par_mas_cerca2[0] + par_mas_cerca[1] = par_mas_cerca2[1] + return d + fin si + + medio = puntos_x[nx / 2].x; + + izquerda = -1 + derecha = ny + para i = 0 mientras que i < ny hacer + si puntos_y[i].x < medio entonces + puntos_y2[++izquerda] = puntos_y[i] + sino + puntos_y2[--derecha] = puntos_y[i] + fin si + fin para + + para i = ny - 1 mientras que derecha < i hacer + par_mas_cerca2[0] = puntos_y2[derecha] + puntos_y2[derecha] = puntos_y2[i] + puntos_y2[i] = par_mas_cerca2[0] + fin para + + min_d = divide_and_conquer_run(puntos_x, nx / 2, puntos_y2, izquerda + 1) + d = divide_and_conquer_run(puntos_x + nx / 2, nx - nx / 2, puntos_y2 + izquerda + 1, ny - izquerda - 1) + + si d < min_d entonces + min_d = d + par_mas_cerca[0] = par_mas_cerca2[0] + par_mas_cerca[1] = par_mas_cerca2[1] + fin si + d = sqrt(min_d) + + izquerda = -1 + derecha = ny + para i = 0 mientras que i < ny hacer + x = puntos_y[i].x - medio + si x <= -d o x >= d entonces + continuar + fin si + si x < 0 entonces + puntos_y2[++izquerda] = puntos_y[i] + sino + puntos_y2[--derecha] = puntos_y[i] + fin si + fin para + + mientras que izquerda >= 0 hacer + x0 = puntos_y2[izquerda].y + d + + mientras que derecha < ny y puntos_y2[derecha].y > x0 hacer + derecha = dercha + 1 + fin mientras + si derecha >= ny entonces + romper + fin si + + x1 = puntos_y2[izquerda].y - d + para i = derecha mientras que i < ny y puntos_y2[i].y > x1 hacer + si distance(puntos_y2[izquerda], puntos_y2[i])) < min_d entonces + min_d = x + par_mas_cerca[0] = puntos_y2[izquerda] + par_mas_cerca[1] = puntos_y2[i] + fin si + fin para + izquerda = izquerda - 1 + fin mientras + return min_d +fin funcion + +funcion divide_and_conquer(puntos, n) { + puntos_x = puntos + puntos_y = puntos + sort(puntos_x, n) + sort(puntos_y, n) + distancia_minimo y par_mas_cerca = divide_and_conquer_run(puntos_x, n, puntos_y, n) + return par_mas_cerca y distancia_minimo +fin funcion diff --git a/src/divide_and_conquer.c b/src/divide_and_conquer.c index 9cb11e4..e37a928 100644 --- a/src/divide_and_conquer.c +++ b/src/divide_and_conquer.c @@ -98,7 +98,7 @@ double divide_and_conquer_run(point_t *points_x, unsigned int nx, point_t *point points_y2[++left] = points_y[i]; } else { - points_y2[--right]= points_y[i]; + points_y2[--right] = points_y[i]; } } @@ -119,7 +119,8 @@ double divide_and_conquer_run(point_t *points_x, unsigned int nx, point_t *point d = sqrt(min_d); free(closest_pair2); - left = -1; right = ny; + left = -1; + right = ny; for (i = 0; i < ny; i++) { x = points_y[i].x - mid; if (x <= -d || x >= d) { @@ -144,12 +145,13 @@ double divide_and_conquer_run(point_t *points_x, unsigned int nx, point_t *point } x1 = points_y2[left].y - d; - for (i = right; i < ny && points_y2[i].y > x1; i++) + for (i = right; i < ny && points_y2[i].y > x1; i++) { if ((x = distance(points_y2[left], points_y2[i])) < min_d) { min_d = x; closest_pair[0] = points_y2[left]; closest_pair[1] = points_y2[i]; } + } left--; }