Está en la página 1de 31

ANALISIS DE ALGORITMOS

TEMA: FUNDAMENTOS DE DIVISIÓN Y CONQUISTA -


RECURSIVIDAD
Temario
 Fundamentos de método de dividir y vencer
 Recursividad
 Recurrencias
Fundamentos de método de dividir y vencer
Dividir para vencer es una técnica natural para las estructuras de datos,
ya que por definición están compuestas por piezas. Cuando una
estructura de tamaño finito se divide, las últimas piezas ya no podrán
ser divididas.
Fundamentos de método de dividir y vencer
• Se divide el problema en subproblemas y, recursivamente, cada
subproblema se divide de nuevo
• Cuando el caso es lo suficientemente sencillo se resuelve utilizando
un algoritmo directo (no recursivo)
• El algoritmo directo debe ser eficiente para problemas sencillos no
importa que no lo sea para problemas grandes
Fundamentos de método de dividir y vencer
• Cada subproblema se resuelve de forma independiente
• Finalmente se combinan las soluciones de todos los subproblemas
para formar la solución del problema original
Fundamentos de método de dividir y vencer
Para poder aplicar métodos de división y conquista debe verificarse
que:
• La formulación recursiva nunca resuelva el mismo subproblema más
de una vez
• La descomposición en subproblemas y la combinación de las
soluciones sean operaciones eficientes
• Los subproblemas sean aproximadamente del mismo tamaño
Ejemplo: dividir y vencer

Programa
Programa original implementado con
métodos
Dinámica N°1
En grupo proceda a investigar sobre el
concepto de modularidad.
“La modularidad es la capacidad de
un sistema informático que ha sido
divido en módulos cohesivos y
débilmente acoplados.”

Luego elaborar un organizador visual


(mapa conceptual, mapa mental, diagrama
de ven, etc.)
Recursividad
• La recursividad es un concepto fundamental en matemáticas y en
computación.
• Es una alternativa diferente para implementar estructuras repetitivas
(ciclos o bucles). Los módulos se hacen llamadas recursivas.
• Se puede usar en toda situación en la cual la solución pueda ser
expresada como una secuencia de movimientos, pasos o
transformaciones gobernadas por un conjunto de reglas no ambiguas.
Recursividad
Caso recursivo: una solución que involucra volver a utilizar la función
original, con parámetros que se acercan más al caso base. Los pasos
que sigue el caso recursivo son los siguientes:
1. El procedimiento se llama a sí mismo
2. El problema se resuelve, tratando el mismo problema pero de
tamaño menor
3. La manera en la cual el tamaño del problema disminuye asegura
que el caso base eventualmente se alcanzará
Ejemplo: Factorial
Escribe un programa que calcule el factorial (!) de un entero no
negativo. He aquí algunos ejemplos de factoriales:

Donde:
n! = n * n-1 * n-2 * ….* 3 * 2 *1 • 1! = 1
n! = n *(n-1)! • 2! = 2 = 2 * 1
• 3! = 6 = 3 * 2 * 1
• 4! = 24 = 4 * 3 * 2 * 1
Ejemplo: Factorial
Ejemplo: Factorial
Aquí podemos ver la secuencia que toma el factorial

1 Si n=0 (base)
N! =
n*(n-1) Si n>0 (recursión)

Un razonamiento recursivo tiene dos partes: la base y la regla recursiva de


construcción. La base no es recursiva y es el punto tanto de partida como de
terminación de la definición.
¿Cómo funciona la recursividad?
¿Por qué escribir programas recursivos?
• Son mas cercanos a la descripción matemática.
• Generalmente mas fáciles de analizar.
• Se adaptan mejor a las estructuras de datos recursivas.
• Los algoritmos recursivos ofrecen soluciones estructuradas,
modulares y elegantemente simples.
¿Cuándo es factible utilizar recursividad?
• Para simplificar el código.
• Cuando la estructura de datos es recursiva ejemplo : árboles.
¿Cuándo no es factible utilizar recursividad?
• Cuando los métodos usen arreglos largos.
• Cuando el método cambia de manera impredecible de campos.
• Cuando las iteraciones sean la mejor opción.
Otros conceptos
• Cuando un procedimiento incluye una llamada a sí mismo se conoce
como recursión directa.
• Cuando un procedimiento llama a otro procedimiento y éste causa
que el procedimiento original sea invocado, se conoce como
recursión indirecta.
Recursión vs iteración
• Repetición
• Iteración: ciclo explícito (se expresa claramente)
• Recursión: repetidas invocaciones a método
• Terminación
• Iteración: el ciclo termina o la condición del ciclo falla
• Recursión: se reconoce el caso base

 En ambos casos podemos tener ciclos infinitos


 Considerar que resulta más positivo para cada problema
Dinámica N° 2
Se desea realizar la multiplicación de dos números a y b. Es decir:
a * b = a + a + (b veces) … + a
La definición recursiva de la multiplicación es:

• Elaborar el programa recursivo en


0 Si b=0 (base) el lenguaje de su preferencia (Java,
a*b = Python, etc.).
a +(a*(b-1)) Si n>0 (recursión) • Luego presentar un análisis de del
tiempo de ejecución para tres
casos.
Recurrencias
• Una función f(n) de los naturales en los reales (o enteros) puede
entenderse como una sucesión (f0, f1, f2, . . .) donde f(n) = fn
• Una recurrencia es una regla que permite calcular el n-ésimo valor fn
de la sucesión a partir de los valores anteriores
• La recurrencia también debe especificar los valores borde de la
sucesión: aquellos valores que una vez conocidos junto con la regla
permiten calcular toda la sucesión.
• En computación nos interesa conocer que tan rápido crecen los
valores fn
Sucesiones recursiva
• Una sucesión es recursiva o recurrente cuando cada termino se
puede expresar utilizando alguno o todos los términos que lo
anteceden, por tanto, para definir una sucesión recursiva es necesario
dar a conocer uno o más de los primeros términos.
• En una sucesión al termino general an, es an-1 y el siguiente es an+1
• Tenemos:
 a1 = 2 Entonces:
 an = 4 + an +1 a2 = 4 + a2-1 = 4 + 2 = 6
a3 = 4 + a3-1 = 4 + a2 = 4 + 6 = 10
a4 = 4 + a4-1 = 4 + a3 = 4 + 10 = 14
a5 = 4 + a5-1 = 4 + a4 = 4 + 14 = 18
Sucesión de Fibonacci
• La sucesión de Fibonacci es una secuencia de números enteros. La
sucesión se define mediante la siguiente formula de recurrencia:
• a1 = 1, a2 = 1 y an = an-1 + an-2
• a3 = a3-1 + a3-2 = a2 + a1 = 1 + 1 = 2
• a4 = a4-1 + a4-2 = a3 + a2 = 2 + 1 = 3
• a5 = a5-1 + a5-2 = a4 + a3 = 2 + 1 = 3
Ejemplo de recurrencia
Considere la recurrencia dada por:
• El valor base f0 = 0
• la regla f(n) = f(n − 1) + n para n > 0

La recurrencia define la sucesión: (0, 1, 3, 6, 10, 15, 21, 28, 36, 45, . . .)

Ejemplo:
 Si n=1, f(1) =f(1-1)+1 = f(0) + 1 = 0 + 1 = 1
 Si n=2, f(2) =f(2-1)+1 = f(1) + 1 = f(1-1) + 1 + 1 = f(0) + 2 = 1 + 2 = 3
Ejemplo

T(n)
1

T(n-1)

T(n) = 1 + T(n-1)

Los bloques if y else son operaciones elementales, por lo que su tiempo de


ejecución es O(1)
Ejemplo del método de sustitución
Factorial(5)
5*factorial(4) - 1
4*factorial(3) - 2
3*factorial(2) - 3 n n>0
2*factorial(1) - 4
1*factorial(0) - 5
1 -6 1 n=0
(O) = n+1
Método de sustitución
• El método de sustitución es una forma de verificar una forma cerrada
obtenida de alguna manera.
• Por lo general lo usamos para dar una cota sobre la tasa de
crecimiento cuando tenemos una pista sobre ella.
• En esencia, el método de sustitución es una prueba por inducción
sobre la tasa de crecimiento (o forma cerrada en algunos casos) de la
recurrencia
Ejemplo del método de sustitución
Considere la recurrencia:

Suponga que creemos f(n) = O(n) y queremos probarlo


Lo primero es hacer la suposición explicita f(n) ≤ cn para alguna constante c > 0, y
mostrar por inducción que f(n) ≤ cn para todos los n en los cuales f esta definida:
Ejemplo del método de sustitución
T(n) = 1 + T(n-1)
= 1 + (1 + T(n-2)) = 2 + T(n-2)
= 2 + (1 + T(n-3)) = 3 + T(n-3)
….
= i + T(n-i)
donde i es el número total de llamadas recursivas
• Es decir, la ultima llamada de T(n-i) es el caso base, cuyo valor es 0:
n - i = 0  i=n -> T(n) = n + T(0) = n+1
• Por tanto, T(n) = n+1 entonces T(n) es O(n)
• La implementación recursiva del calculo del factorial es de orden lineal.
Ejemplo del método de árbol recursivo
La secuencia de Fibonacci es una recursión clásica:
F(1)=1,F(2)=1, F(n) = F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)

if ((n == 0) || (n == 1))
return 1;
else
return fibonacci(n-1) + fibonacci(n-2);
Ejemplo del método de árbol recursivo
f(5) 0
Fibonacci(5)

f(4) f(3) 1

f(3) f(2) f(2) f(1) 2

f(2) f(1) f(1) f(0) f(1) f(0) 3

f(1) f(0) 4

20 21 22 23 24 ….. 2n+1 (O) = 2n

También podría gustarte