Merge branch 'informe' of UBB/points into master

This commit is contained in:
Chris Cromer 2018-12-14 20:53:14 -03:00 committed by Gitea
commit 7beed00f63
5 changed files with 120 additions and 11 deletions

View File

@ -70,9 +70,11 @@ Xavier Canales
\pagenumbering{arabic}
\section{Pseudo código}
\subsection{Brute Force}
\lstinputlisting{pseudo/brute_force.txt}
\newpage
\subsection{Divide and Conquer}
\lstinputlisting{pseudo/divide_and_conquer.txt}
\newpage
\section{Resultados}
@ -80,23 +82,23 @@ Xavier Canales
\subsection{Análisis temporal}
\subsubsection{Brute Force}
\underline{Caso Promedio:} $ \Theta(n log n)) $ \\
\bigskip
Para el algoritmo de fuerza bruta el tiempo de respuesta es igual en todos los casos de $ n^2 $, esto se debe a que este donde este los puntos mas cercanos este recorrerá todo de igual forma. Esto es netamente debido a el cómo se programó las funciones con ciclos for anidados que son altamente costosos en tiempo.\bigskip
\underline{Peor Caso:} $ O(n log n) $ \\
\bigskip
El peor caso es similar al caso promedio.\bigskip
\underline{Mejor Caso:} $ \Omega(n log n)$ \\
\bigskip
El mejor caso es similar al caso promedio.\bigskip
\subsubsection{Divide and Conquer}
\underline{Caso Promedio:} $ \Theta(n log n)) $ \\
\bigskip
Para el algoritmo de dividir y conquistar se repite lo del análisis anterior que es la misma complejidad en todos los casos, de nuevo producto de que tiene que recorrer todo el mapa de puntos para llegar a saber cuales son los mas cercanos. Aquí es $ n log(n) $, ya que este algoritmo divide el mapa para y compara las mitades separadamente lo cual es mucho mas eficiente que el caso anterior.\bigskip
\underline{Peor Caso:} $ O(n log n) $ \\
\bigskip
El peor caso es similar al caso promedio.\bigskip
\underline{Mejor Caso:} $ \Omega(n log n)$ \\
\bigskip
El mejor caso es similar al caso promedio.\bigskip
\newpage
\subsection{Datos}
@ -108,9 +110,9 @@ La siguiente tabla contiene los resultados de las pruebas de los 2 algoritmos me
\hline
\rule[-1ex]{0pt}{3.5ex} & Brute Force & Divide and Conquer \\
\hline
\rule[-1ex]{0pt}{3.5ex} 1.000.000 & 0[s] & 0[s] \\
\rule[-1ex]{0pt}{3.5ex} 1.000.000 & 15403.951[s] & 3[s] \\
\hline
\rule[-1ex]{0pt}{3.5ex} 5.000.000 & 0[s] & 0[s] \\
\rule[-1ex]{0pt}{3.5ex} 5.000.000 & 372984[s] & 11.210[s] \\
\hline
\end{tabular}
\end{center}
@ -118,8 +120,14 @@ 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 el desarrollo de este trabajo se nos pidió comparar dos algoritmos que ambos buscaban la menor distancia entre dos puntos. El primero fue el de fuerza bruta el cual consistía en un algoritmo ingenuo el cual buscaba comparando con 2 ciclos for, realizaba lo pedido de una de las peores formas costando muy caro en cuanto a tiempo a medida que aumentaban los puntos. Por otro lado, el segundo utilizaba un método recursivo en el cual se dividia a la mitad y cada una era comparada por separado, siendo este el mejor. A cantidades bajas de puntos la diferencia entre tiempos no era tan grande, pero a medida que incrementaba la curva de brute force despegaba hacía arriba. Finalmente, podemos terminar este trabajo de investigación con que para un mismo algoritmo pese a haber varias formas de programar una solución hay algunas que son completamente intratables todo depende de la cantidad de los datos de entrada.
\par
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} $
\end{document}

BIN
doc/graph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -0,0 +1,15 @@
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]
fin si
fin para
fin para
return par_mas_cerca y distancia_minimo
fin funcion

View File

@ -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

View File

@ -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--;
}