Professional Documents
Culture Documents
..
Lab03 - ADA
CUI:20103680
27 de octubre de 2019
1. To Do
El Closest Pair Problem es viable resolverlo mediante dos tecnicas conocidas en el diseño
de algoritmos (Brute-Force y Divide and Conquer), seguidamente se demostrara la Com-
plejidad Temporal de ambos metodos de forma empirica y teorica con los mismos datos,
generando un csv file y graficandolo en RStudio.
1.1. ALGORITHMS
A continuación se presenta los algoritmos mencionados en la sección anterior.
1
Algoritmo 2 Algoritmo de Divide y Venceras - Closest Pair Problem
1: procedure divideAndConquer(points)
2: pointsSortedByX ← points
3: pointsSortedByY ← points
4: return ← divideAndConquer(pointsSortedByX,pointsSortedByY)
5: procedure divideAndConquer(pointsSortedByX,pointsSortedByY)
6: if pointsSortedByX.size <= 3 then
7: return ← bruteForce(pointsSortedByX)
8: lef tOf Center ← pointsSortedByX
9: rightOf Center ← pointsSortedByX
10: tempList ←sortByY(leftOfCenter)
11: closestP air ← divideAndConquer(leftOfCenter,tempList)
12: tempList ←sortByY(rightOfCenter)
13: closestP airRight ← divideAndConquer(rightOfCenter,tempList)
14: closestP air ←min(closestPair,closestPairRight)
15: shortestDistance ← closestPair.distance
16: centerX ← rightOfCenter.get(0).x;
17: tempList.clear
18: foreach P oint ∈ pointsSortedByY do
19: tempList ← centerX - Point.x <shortestDistance
20: end foreach
21: for tempList do
22: P oint1 ← tempList.get(i)
23: for tempList do
24: P oint2 ← tempList.get(j)
25: if Point2.y-Point1.y >=shortestDistance then
26: BREAK
27: if P air.distance(point1, point2) < closestPair.distance then
28: closestP air ← (Point1,Point2,distance(point1, point2))
29: shortestDistance ← distance(point1, point2)
30: return ← closestPair
2
1.2. CODING
Para la implementación se uso JAVA, en la Clase ClosestPair se encuentra las funcio-
nes de clase divideAndConquer y bruteForce, las cuales son llamadas por TimeWatch,
generando objetos de la Clase Point desde 100 a 1000000 con pasos de 500, ejecutan-
do bruteForce y luego divideAndConquer, para posteriormente guardar en un archivo
ClosestP airT est100to1000000.csv el numero de datos y los respectivos tiempos de eje-
cución para cada algoritmo.
p u b l i c c l a s s Point {
p u b l i c f i n a l double x ;
p u b l i c f i n a l double y ;
p u b l i c Point ( double x , double y ) {
this .x = x;
this .y = y;
}
public String toString () {
return " ( " + x + " , ␣" + y + " ) " ; }
}
p u b l i c c l a s s TimeWatch {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) throws IOException {
L i s t <S t r i n g > r e g = new A r r a y L i s t <S t r i n g > ( ) ;
L i s t <Point> p o i n t s = new A r r a y L i s t <Point > ( ) ;
F i l e W r i t e r f w r i t e r = new F i l e W r i t e r ( " C l o s e s t P a i r _ T e s t 1 0 0 t o 5 0 0 . c s v " ) ;
S t r i n g time = n u l l , tmp = n u l l ;
// b o o l e a n swDQ_FB = f a l s e ; // F a l s e i s ForceBruta
f o r ( i n t i = 1 0 0 ; i <= 5 0 0 ; i += 1 0 0 ) {
AlgorithmOne a l g o r i t h m = new AlgorithmOne ( ) ;
System . out . p r i n t ( " T e s t i n g ␣ " + a l g o r i t h m . d e s c r i p t i o n ( ) + " : ␣ " ) ;
generarRandData ( i , p o i n t s ) ;
// f i r s t time i s swDQ_FB = 0
f o r ( i n t swDQ_FB = 0 ; swDQ_FB <= 1 ; swDQ_FB++) {
i f (swDQ_FB == 0 )
time = " " ;
l o n g s t a r t _ t i m e = System . c u r r e n t T i m e M i l l i s ( ) ;
l o n g nano_time_start = System . nanoTime ( ) ;
b o o l e a n s t a t e = a l g o r i t h m . run ( p o i n t s , swDQ_FB ) ;
i f ( state )
System . out . p r i n t l n ( " A l l ␣OK. ␣ ␣ " + swDQ_FB ) ;
else
System . out . p r i n t l n ( " Something ␣ went ␣ wrong ! " ) ;
l o n g end_time = System . c u r r e n t T i m e M i l l i s ( ) ;
l o n g nano_time_end = System . nanoTime ( ) ;
f l o a t tm = ( nano_time_end − nano_time_start ) / 1000000000F ;
System . out . p r i n t l n ( tm ) ;
i f (swDQ_FB == 0 )
time = i + " , " + S t r i n g . v a l u e O f ( tm) + " , " ;
e l s e { time += S t r i n g . v a l u e O f ( tm ) ; }
}
System . out . p r i n t l n ( time ) ;
r e g . add ( time ) ;
f w r i t e r . w r i t e ( time ) ;
f w r i t e r . append ( ’ \n ’ ) ;
}
3
fwriter . flush ();
fwriter . close ();
}
p r i v a t e s t a t i c v o i d generarRandData ( i n t numPoints , L i s t <Point> p o i n t s ) {
Random r = new Random ( ) ;
f o r ( i n t i = 0 ; i < numPoints ; i ++)
p o i n t s . add ( new P o i n t ( r . nextDouble ( ) , r . nextDouble ( ) ) ) ;
System . out . p r i n t l n ( " Generated ␣ " + numPoints + " ␣random␣ p o i n t s " ) ;
}
}
p u b l i c c l a s s AlgorithmOne implements I A l g o r i t h m {
public String description () {
r e t u r n new S t r i n g ( " C l o s e s t ␣ P a i r ␣ Problem " ) ;
}
p u b l i c b o o l e a n run ( L i s t <Point> p o i n t s , i n t swDQ_FB) {
i f (swDQ_FB!=0) {
P a i r d q C l o s e s t P a i r = C l o s e s t P a i r . divideAndConquer ( p o i n t s ) ;
System . out . p r i n t l n ( " D i v i d e ␣and␣ c onqu er : ␣ " + d q C l o s e s t P a i r ) ;
} else {
Pair bfClosestPair = ClosestPair . bruteForce ( points ) ;
System . out . p r i n t l n ( " Brute ␣ f o r c e : ␣ " + b f C l o s e s t P a i r ) ;
}
return true ;
}
@Override
p u b l i c b o o l e a n run ( ) {
return f a l s e ;
}
}
public c l a s s Pair {
p u b l i c Point point1 = n u l l ;
p u b l i c Point point2 = n u l l ;
p u b l i c double d i s t a n c e = 0 . 0 ;
p u b l i c P a i r ( ) {}
p u b l i c Pair ( Point point1 , Point point2 ) {
t h i s . point1 = point1 ;
t h i s . point2 = point2 ;
calcDistance ( ) ;
}
p u b l i c v o i d update ( P o i n t p o i n t 1 , P o i n t p o i n t 2 , d o u b l e d i s t a n c e ) {
t h i s . point1 = point1 ;
t h i s . point2 = point2 ;
this . distance = distance ;
}
public void calcDistance () {
t h i s . d i s t a n c e = d i s t a n c e ( point1 , point2 ) ;
}
public String toString () {
r e t u r n p o i n t 1 + "−" + p o i n t 2 + " ␣ : ␣ " + d i s t a n c e ;
}
p u b l i c s t a t i c d o u b l e d i s t a n c e ( P o i n t p1 , P o i n t p2 ) {
d o u b l e x d i s t = p2 . x − p1 . x ;
d o u b l e y d i s t = p2 . y − p1 . y ;
r e t u r n Math . hypot ( x d i s t , y d i s t ) ; }
}
4
public class ClosestPair {
p u b l i c s t a t i c P a i r b r u t e F o r c e ( L i s t <? e x t e n d s Point> p o i n t s ) {
i n t numPoints = p o i n t s . s i z e ( ) ;
i f ( numPoints < 2 )
return null ;
P a i r p a i r = new P a i r ( p o i n t s . g e t ( 0 ) , p o i n t s . g e t ( 1 ) ) ;
i f ( numPoints > 2 ) {
f o r ( i n t i = 0 ; i < numPoints − 1 ; i ++) {
Point point1 = p o i n t s . get ( i ) ;
f o r ( i n t j = i + 1 ; j < numPoints ; j ++) {
Point point2 = p o i n t s . get ( j ) ;
double d i s t a n c e = Pair . d i s t a n c e ( point1 , point2 ) ;
i f ( distance < pair . distance )
p a i r . update ( p o i n t 1 , p o i n t 2 , d i s t a n c e ) ;
}
}
}
return pair ;
}
p r i v a t e s t a t i c P a i r divideAndConquer
( L i s t <?e x t e n d s Point>pointsSortedByX , L i s t <?e x t e n d s Point>pointsSortedByY ) {
i n t numPoints = pointsSortedByX . s i z e ( ) ;
i f ( numPoints <= 3 ) r e t u r n b r u t e F o r c e ( pointsSortedByX ) ;
i n t d i v i d i n g I n d e x = numPoints >>> 1 ;
5
L i s t <? e x t e n d s Point> l e f t O f C e n t e r
=pointsSortedByX . s u b L i s t ( 0 , d i v i d i n g I n d e x ) ;
L i s t <? e x t e n d s Point> r i g h t O f C e n t e r
=pointsSortedByX . s u b L i s t ( d i v i d i n g I n d e x , numPoints ) ;
tempList . c l e a r ( ) ;
t e m p L i s t . add All ( r i g h t O f C e n t e r ) ;
sortByY ( t e m p L i s t ) ;
P a i r c l o s e s t P a i r R i g h t = divideAndConquer ( r i g h t O f C e n t e r , t e m p L i s t ) ;
tempList . c l e a r ( ) ;
double s h o r t e s t D i s t a n c e = c l o s e s t P a i r . d i s t a n c e ;
d o u b l e cen terX = r i g h t O f C e n t e r . g e t ( 0 ) . x ;
f o r ( P o i n t p o i n t : pointsSortedByY )
i f ( Math . abs ( cen terX − p o i n t . x ) < s h o r t e s t D i s t a n c e )
t e m p L i s t . add ( p o i n t ) ;
f o r ( i n t i = 0 ; i < t e m p L i s t . s i z e ( ) − 1 ; i ++) {
Point point1 = tempList . get ( i ) ;
f o r ( i n t j = i + 1 ; j < t e m p L i s t . s i z e ( ) ; j ++) {
Point point2 = tempList . get ( j ) ;
i f ( ( p o i n t 2 . y − p o i n t 1 . y ) >= s h o r t e s t D i s t a n c e )
break ;
double d i s t a n c e = Pair . d i s t a n c e ( point1 , point2 ) ;
i f ( distance < closestPair . distance ) {
c l o s e s t P a i r . update ( p o i n t 1 , p o i n t 2 , d i s t a n c e ) ;
shortestDistance = distance ;
}
}
6
1.3. RESULTADOS
Inicialmente se realizo una test de datos de 100 a 500 datos, comprobando el correcto
funcionamiento de ambos algoritmos al coincidir con el mismo par de Puntos mas Cer-
cano. Seguidamente para tener un panorama mas amplio, se aplico con la generación de
100 a 1000000 con paso de 900 datos, obteniendo los resultados en otro archivo csv.
7
1.4. ¿What is the average cost of the algorithm implemented?
¿What is the unit to measure cost?
Como en todo el algoritmo debe analizarse por el costo de operación y el número de veces
que se ejecutara. El costo promedio queda demostrado de igual manera que el calculo
del numero de ietraciones consiguiendo un orden O(n)=log(n), la base del logaritmo es
2 porque reduce constantemente a la mitad.
1.4.1. Bisección
Se presenta el Algoritmo 3 para calcular la altura de un nodo. En caso de que el nodo no
exista se retornará cero. De esta forma usando la notacion Big-O ∼ O(n) = 7 + 10 ∗ n,
el valor de c=17 y n0=1
8
1.5. ¿Are there a relation between the theory cost and the
implementation cost?
Efectivamente claro que si, el costo de implementación depende de factores como single vs
multi processor, read/write memory, 32bits or 64bits, y por ultimo pero muy importante
el tipo de entrada, el costo promedio se calcula solo con el tipo de entrada y en el peor
de los casos, por ello es una aproximación de cota superior.
1.6.1. Comparación
Ambos metodos son de orden n y considerando la misma precision para diferentes fun-
ciones se puede concluir que la unicac diferencia es en el numero de iteraciones(Analisis
de Complejidad Temporal)
1
http://www.graphviz.org/Home.php
9
(a) (b)
2. Implementación
Para la visualización de las iteraciones se imprimia cada una con los valores de n, xl, c,
xr, MEP2 , además se imprime el calculo de las iteraciones (4.PNG) para corroboran la
coincidencia(5.PNG).
Implementamos nuestra funcion f(x) y bisección(a,b,tol)(3.PNG):
def f (x ) :
r e t u r n x∗∗2−11
w h i l e (MEP>t o l ) :
c=( xr+x l ) / 2 . 0 #punto medio
p r i n t ( n , x l , c , xr , MEP)
prod = f ( x l ) ∗ f ( c )
i f prod < 0 :
xr=c
else :
x l=c
MEP=(xr−x l ) / 2 . 0
n=n+1
return c
answer = b i s e c t i o n ( 0 . 0 , 1 1 . 0 , 1 e −3)
p r i n t ( " ␣ B i s e c t i o n ␣Mthod␣ Gives ␣ Root ␣At␣x␣=" , answer )
2
http://www.graphviz.org/Home.php
10
3. Resultados y conclusiones
Se realizaron pruebas validando el funcionamiento de la implementación, por medio de
MATLAB y su comando roots, en la Figura ?? presentamos el resultado de Matlab y de
Python
11
3.1. Conclusiones
El metodo de la biseccion es uno que puede hallar cualquier raiz de una función po-
linomica, es un metodo conocido como metodo cerrado, porque esta limitado por un
intervalo, solo proporciona una raiz y para funciones no transendentales se dene usar
metodos expuestos en la referencia 1 seccion 2.9
Referencias
[1] Metodos Numericos Aplicados a la Ingenieria, Antonio Nieves Hurtado, Doklady Aka-
demia Nauk SSSR, ed. 4, pag. 79–98, 2014
[2] Time complexity analysis - How to calculate running time?-Youtube, Reed, Bruce,
Proceedings of the thirty-second annual ACM symposium on Theory of computing,
pag. 479–483, ACM, 2000
12