Finish informe #4
@ -70,9 +70,11 @@ Xavier Canales
|
|||||||
\pagenumbering{arabic}
|
\pagenumbering{arabic}
|
||||||
\section{Pseudo código}
|
\section{Pseudo código}
|
||||||
\subsection{Brute Force}
|
\subsection{Brute Force}
|
||||||
|
\lstinputlisting{pseudo/brute_force.txt}
|
||||||
|
|
||||||
\newpage
|
\newpage
|
||||||
\subsection{Divide and Conquer}
|
\subsection{Divide and Conquer}
|
||||||
|
\lstinputlisting{pseudo/divide_and_conquer.txt}
|
||||||
|
|
||||||
\newpage
|
\newpage
|
||||||
\section{Resultados}
|
\section{Resultados}
|
||||||
@ -80,23 +82,23 @@ Xavier Canales
|
|||||||
\subsection{Análisis temporal}
|
\subsection{Análisis temporal}
|
||||||
\subsubsection{Brute Force}
|
\subsubsection{Brute Force}
|
||||||
\underline{Caso Promedio:} $ \Theta(n log n)) $ \\
|
\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) $ \\
|
\underline{Peor Caso:} $ O(n log n) $ \\
|
||||||
\bigskip
|
El peor caso es similar al caso promedio.\bigskip
|
||||||
|
|
||||||
\underline{Mejor Caso:} $ \Omega(n log n)$ \\
|
\underline{Mejor Caso:} $ \Omega(n log n)$ \\
|
||||||
\bigskip
|
El mejor caso es similar al caso promedio.\bigskip
|
||||||
|
|
||||||
\subsubsection{Divide and Conquer}
|
\subsubsection{Divide and Conquer}
|
||||||
\underline{Caso Promedio:} $ \Theta(n log n)) $ \\
|
\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) $ \\
|
\underline{Peor Caso:} $ O(n log n) $ \\
|
||||||
\bigskip
|
El peor caso es similar al caso promedio.\bigskip
|
||||||
|
|
||||||
\underline{Mejor Caso:} $ \Omega(n log n)$ \\
|
\underline{Mejor Caso:} $ \Omega(n log n)$ \\
|
||||||
\bigskip
|
El mejor caso es similar al caso promedio.\bigskip
|
||||||
|
|
||||||
\newpage
|
\newpage
|
||||||
\subsection{Datos}
|
\subsection{Datos}
|
||||||
@ -108,9 +110,9 @@ La siguiente tabla contiene los resultados de las pruebas de los 2 algoritmos me
|
|||||||
\hline
|
\hline
|
||||||
\rule[-1ex]{0pt}{3.5ex} & Brute Force & Divide and Conquer \\
|
\rule[-1ex]{0pt}{3.5ex} & Brute Force & Divide and Conquer \\
|
||||||
\hline
|
\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
|
\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
|
\hline
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{center}
|
\end{center}
|
||||||
@ -118,8 +120,14 @@ La siguiente tabla contiene los resultados de las pruebas de los 2 algoritmos me
|
|||||||
\newpage
|
\newpage
|
||||||
\subsection{Gráfico}
|
\subsection{Gráfico}
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
\includegraphics[width=0.96\textwidth,height=0.96\textheight,keepaspectratio]{graph.png}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
\newpage
|
\newpage
|
||||||
\section{Conclusiones}
|
\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} $
|
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}
|
\end{document}
|
||||||
|
BIN
doc/graph.png
Normal file
BIN
doc/graph.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
15
doc/pseudo/brute_force.txt
Normal file
15
doc/pseudo/brute_force.txt
Normal 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
|
84
doc/pseudo/divide_and_conquer.txt
Normal file
84
doc/pseudo/divide_and_conquer.txt
Normal 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
|
@ -119,7 +119,8 @@ double divide_and_conquer_run(point_t *points_x, unsigned int nx, point_t *point
|
|||||||
d = sqrt(min_d);
|
d = sqrt(min_d);
|
||||||
free(closest_pair2);
|
free(closest_pair2);
|
||||||
|
|
||||||
left = -1; right = ny;
|
left = -1;
|
||||||
|
right = ny;
|
||||||
for (i = 0; i < ny; i++) {
|
for (i = 0; i < ny; i++) {
|
||||||
x = points_y[i].x - mid;
|
x = points_y[i].x - mid;
|
||||||
if (x <= -d || x >= d) {
|
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;
|
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) {
|
if ((x = distance(points_y2[left], points_y2[i])) < min_d) {
|
||||||
min_d = x;
|
min_d = x;
|
||||||
closest_pair[0] = points_y2[left];
|
closest_pair[0] = points_y2[left];
|
||||||
closest_pair[1] = points_y2[i];
|
closest_pair[1] = points_y2[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
left--;
|
left--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user