Sie sind auf Seite 1von 6

Cálculo de elementos de la sucesión de Fibonacci:

Algoritmos “dividir y vencer” y “programación dinámica”


Análisis y verificación de algoritmos
Octubre 2016

Santiago Garcia 1220011602


Jhon Muñoz 1310013384
Nicolay Villada 1310010989
Miller Carreño 1320012157

Sucesión de Fibonacci

Está definida como

( )

( ) ( )

Por lo tanto se deben sumar los elementos mediante un bucle que debe ejecutarse desde 2 hasta
n. Cada iteración debe guardar el último y el penúltimo término, para lo que se usan dos variables,
a las que irán cambiando sus valores. El sub algoritmo aceptará como entrada una variable entera
y devolverá un valor también entero.

Para realizar el cálculo de los números de la sucesión de Fibonacci usaremos dos técnicas,
Programación Dinámica y Exponenciación sobre una matriz 2x2.

Programación Dinámica

public static long fibDin (int n) {

int a = 0;
int b = 1;
int c = 1;

if (n<=1){
return n;
}
for (int i=1; i<n; i++){
c = a+b;
a = b;
b = c;
}
return c;
}
Pseudocódigo del algoritmo

entero función fibDin (E entero : n)


var
entero : a, b, c, i
inicio
a0
b1
c1
si n <= 1 entonces
escribir (n)
fin_si
desde i = 1 hasta n hacer
ca+b
ab
bc

fin_desde
escribir (n)
fin

 Éste algoritmo es más lento que el de la exponenciación sobre matriz 2x2


 Éste algoritmo no se puede usar para hallar números negativos
 Para valores pequeños de n funciona bien, para los grandes no es eficaz
 La complejidad del algoritmo es O (n)

Exponenciación usando matriz 2x2

El algoritmo está basado en la siguiente identidad (que puede ser probada por inducción
matemática)

( ) ( )

Por lo que la matriz [1, 1, 1, 0] se multiplica “n” veces, siendo equivalente al número “n” que se
quiera calcular de la sucesión de Fibonacci, al terminar, el número ubicado en la posición 0 será el
resultado.

Código del algoritmo

package fibonacci;

import java.math.BigInteger;
import java.util.Stack;
public class fibonacci {

private static final BigInteger[][] FIB_M = new


BigInteger[][]{{BigInteger.ONE,BigInteger.ONE},{BigInteger.ONE,BigInteger.ZERO}}
;

public static BigInteger fibonacci(BigInteger n){

BigInteger[][] M = new
BigInteger[][]{{BigInteger.ONE,BigInteger.ONE},{BigInteger.ONE,BigInteger.ZERO}}
;
BigInteger two = new BigInteger("2");

if(n.compareTo(BigInteger.ZERO) < 0){throw new IllegalArgumentException("n debe


ser igual o mayor a cero");}
else if(n.equals(BigInteger.ZERO)){return BigInteger.ZERO;}
else if(n.equals(BigInteger.ONE)) {return M[1][0];}

Stack<BigInteger> potencia= new Stack<>();


while(n.compareTo(BigInteger.ONE) > 0) {
potencia.push(n);
n = n.divide(two);
}

while(!potenciaStack.isEmpty()){
BigInteger p = potencia.pop();
multiplicar(M, M);
if(p.mod(two).equals(BigInteger.ONE)){
multiplciar(M, FIB_M);
}
}

// System.out.println(M[1][0]);
return M[1][0];
}

private static void multiplicar(BigInteger[][] m, BigInteger[][] n) {


BigInteger a = m[0][0].multiply( n[0][0]).add(m[0][1].multiply(n[1][0]));
BigInteger b = m[0][0].multiply( n[0][1]).add(m[0][1].multiply(n[1][1]));
BigInteger c = m[1][0].multiply( n[0][0]).add(m[1][1].multiply(n[1][0]));
BigInteger d = m[1][0].multiply( n[0][1]).add(m[1][1].multiply(n[1][1]));

m[0][0] = a; m[0][1] = b;
m[1][0] = c; m[1][1] = d;
}
}
Pseudocódigo del algoritmo

Estatico matriz FIN_M = {{1,1},{1,0}}

entero función fibonacci


matriz m = {{1,1},{1,0}}
si n < 0 entonces devolver error
si n == 0 devolver 0
si n = 1 devolver m[1][0]

pila potencia
mientras (n > 0)
agregar n a la pila
n = n/2

multiplicar las matrices

a = m[0][0]*( n[0][0])+(m[0][1]*(n[1][0]));
b = m[0][0]*( n[0][1])+(m[0][1]*(n[1][1]));
c = m[1][0]*( n[0][0])+(m[1][1]*(n[1][0]));
d = m[1][0]*( n[0][1])+(m[1][1]*(n[1][1]));

m[0][0] = a; m[0][1] = b;
m[1][0] = c; m[1][1] = d;

 Se reducen operaciones innecesarias para valores altos de n


 Es más rápido que el algoritmo de programación dinámica
 Se usan matrices
 La complejidad del algoritmo es O(log(n))
CUADRO COMPARATIVO
PROGRAMACIÓN DINÁMICA EXPONENCIACIÓN
Eficiencia El algoritmo efectúa las operaciones El uso de las matrices ayuda a
correctamente para valores pequeños reducir las operaciones para
de n pero con valores más grandes se los valores más elevados de n
vuelve lento haciéndolo menos haciendo que el algoritmo sea
eficiente más rápido que la contraparte
dinámica y por lo tanto mas
eficiente
Facilidad para El algoritmo es bastante sencillo Para la comprensión del
comprender el consta de una serie de asignaciones algoritmo es necesaria una
algoritmo de valores a las variables y un ciclo comprensión de uso de las
por lo tanto tiene una dificultad de matrices y como beneficia la
comprensión baja velocidad por lo tanto tiene
una complejidad media
Facilidad para Tiene una gran facilidad de ser El algoritmo puede ser mas
implementar el implementado como se puede ver en difícil de implementar, ya que
algoritmo(JAVA) unas sencillas de código, pero es la hay que añadir el manejo de
simplicidad lo que a su vez hace que el matrices y además para
algoritmo se vuelva menos eficiente manejar grandes valores se
para grandes valores de n utiliza BigInteger
Complejidad Lineal Logarítmica O(log n)
modificable Como el algoritmo es bastante simple El algoritmo esta
no representa un mayor esfuerzo el implementado según las
modificarlo ya sea para aceptar especificaciones establecidas
nuevas variables o también podría ser por lo cual una modificación
usado de base para otro algoritmo podría representar una mayor
dificultad, pero puede ser
usado como base para un
algoritmo con diferentes
especificaciones
finitud El algoritmo se ejecutará para valores El algoritmo se ejecutara hasta
pequeños hasta que cumpla la cumplir la condición y tolera
condición propuesta, pero para valores más altos y una mayor
valores más grandes puede que el cantidad de operaciones por lo
algoritmo no llegue a retornar que podríamos decir que es
finito
Cibergrafia

https://www.codechef.com/wiki/tutorial-dynamic-programming
https://www.nayuki.io/page/fast-fibonacci-algorithms
https://www.geeksforgeeks.org/program-for-nth-fibonacci-number/
http://blog.gomox.com.ar/2008/11/prueba-source-higlight.html
http://kukuruku.co/hub/algorithms/the-nth-fibonacci-number-in-olog-n

Das könnte Ihnen auch gefallen