You are on page 1of 12

Universidad Nacional de San Agustín, Escuela de Ingenieria de Sistemas

..

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.

Algoritmo 1 Algoritmo de Fuerza Bruta


1: procedure bruteForce(points)
2: numP oints ← points.size
3: if numPoints <2 then
4: return ← null
5: P air ← (points.get(0),points.get(1))
6: if numPoints >2 then
7: for points do
8: P oint1 ← points.get(i)
9: for points do
10: P oint2 ← points.get(j)
11: distance ←Pair.distance(point1, point2)
12: if distance <Pair.distance then
13: P air ← (Point1,Point2,distance(point1, point2))
14: return ← Pair

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 u b l i c s t a t i c v o i d sortByX ( L i s t <? e x t e n d s Point> p o i n t s ) {


C o l l e c t i o n s . s o r t ( p o i n t s , new Comparator<Point >() {
p u b l i c i n t compare ( P o i n t p o i n t 1 , P o i n t p o i n t 2 ) {
i f ( point1 . x < point2 . x)
r e t u r n −1;
i f ( point1 . x > point2 . x)
return 1;
return 0;
}
});
}

p u b l i c s t a t i c v o i d sortByY ( L i s t <? e x t e n d s Point> p o i n t s ) {


C o l l e c t i o n s . s o r t ( p o i n t s , new Comparator<Point >() {
p u b l i c i n t compare ( P o i n t p o i n t 1 , P o i n t p o i n t 2 ) {
i f ( point1 . y < point2 . y)
r e t u r n −1;
i f ( point1 . y > point2 . y)
return 1;
return 0;
}
});
}

p u b l i c s t a t i c P a i r divideAndConquer ( L i s t <? e x t e n d s Point> p o i n t s ) {


L i s t <Point> pointsSortedByX = new A r r a y L i s t <Point >( p o i n t s ) ;
sortByX ( pointsSortedByX ) ;
L i s t <Point> pointsSortedByY = new A r r a y L i s t <Point >( p o i n t s ) ;
sortByY ( pointsSortedByY ) ;
r e t u r n divideAndConquer ( pointsSortedByX , pointsSortedByY ) ;
}

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 ) ;

L i s t <Point> t e m p L i s t = new A r r a y L i s t <Point >( l e f 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 = divideAndConquer ( l e f t O f C e n t e r , t e m p L i s t ) ;

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 ) ;

i f ( closestPairRight . distance < closestPair . distance )


closestPair = closestPairRight ;

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

Figura 1.1: Testing CSV File, 100 to 500 data

100 a 1000000 con paso de 900 datos, obteniendo los resultados en otro archivo csv.

Figura 1.2: CSV File, 100 to 1000000 data

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

Algoritmo 3 Algoritmo de Bisección


1: procedure Bisección(a,b,tol)
2: XL ← a
3: XR ← b
4: M EP ← (b - a)/2
5: while MEP >tol do
6: C ← (a + b)/2
7: SW ← f(xl)*f(c)
8: if SW <0 then
9: XR ← c
10: else
11: XL ← c
12: M EP ← UPDATE

1.4.2. Función Generica Nth Root


En este caso al hallar la raiz enesima a de un numero b, es un valor x y moviendo terminos
a un extremo obtenemos las siguiente forma f(x)∼ xa − b = 0 ?? para calcular la funcion
enesima de cualquier.

1.4.3. Función Sign


El metodo de la bisección se carteriza por encontrar una diferencia de signo entre los
valores de f(x), los cuales pueden quedar definidos por menos-mas o mas-menos, una ope-
racion matematica que puede ayudarnos es la multiplicación de menos-mas ó mas-menos
nos da menos y especificando solo un cambio queda definido el otro automaticamente

Algoritmo 4 Función Signo


1: procedure Switch
2: SW ← f(xl)*f(c)
3: if SW <0 then
4: XR ← c
5: else
6: XL ← c

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. ¿Find another algorithm to resolve the nth root problem,


explain it and make a comparison between both.?
Como otro metodo es el de Netwon Rapson,a partir de un único valor inicial x0 que no es
demasiado lejos de una raíz nos movemos a lo largo de la tangente a su intersección con
el eje x, y tomamos que la próxima aproximación. Esto continúa hasta que los valores x
sucesivos están suficientemente cerca o el valor de la función está suficientemente cerca
de cero. Seguidamente se adjunta el codigo1

#programa : newton rhapson


#f u n c i o n : c a l c u l a r l a r a i z de f u n c i o n e s t r a s c e n d e n t e s o a l g e b r a i c a s
import sympy a s sy
#x e s un s i m b o l o
x=sy . symbols ( ’ x ’ )
#f u n c i o n
f u n c i o n=sy . exp(−x)−x
#primera d e r i v a d a de l a f u n c i o n
d e r i v a d a=sy . d i f f ( f u n c i o n , x )
#v a r i b l e s
#xo v a l o r i n i c i a l para l a c o n v e r g e n c i a
x_0=0
xr=x_0
#e r r o r aproximado r e l a t i c o p o r c e n t u a l
ea =100/100
#e r r o r e s t i m a d o
e s =0.001/100
c o n t a d o r=−1
p r i n t ( " i \ t x i \ t e a %" )
w h i l e ea>e s :
xra=xr
c o n t a d o r+=1
newton_rhapson=x−( f u n c i o n / d e r i v a d a )
#s e s u b t i t u y e x por x r a c o n t i n u a n d i c o n s e e v a l u a
xr=newton_rhapson . e v a l f ( s u b s={x : xr } )
#e r r o r aproximado r e l a t i v o p o r c e n t u a l
ea=sy . Abs ( ( ( xr−xra ) / xr ) ∗ 1 0 0 )
#r e s u l t a d o
p r i n t ( contador , " \ t " , xra , " \ t " , ea )

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)

Figura 1.3: Número de Iteraciones (a) Newtown Rapson, (b) Bisección.

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

def bisection (a , b , tol ) :


n=0
x l=a
xr=b
i t r =(math . l o g ( b/ t o l ) ) / math . l o g ( 2 )
p r i n t ( "Numero␣ de ␣ i t e r a c i o n e s ␣ c a l c u l a d a s ␣ i t r ␣=" , i t r )
MEP=(xr−x l ) / 2 . 0
#np . a b s ( x l −x r)>= t o l

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

Figura 3.1: Comprobación de resultados Matlab-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

[3] Complexity of Algoritmic for Iterative Solution of Not Linear Equation

12

You might also like