recursion - recursivos - ejemplo algoritmo complejidad exponencial
Determinando la complejidad de las funciones recursivas(notación Big O) (3)
La complejidad de tiempo, en notación Big O, para cada función, está en orden numérico:
- La primera función se llama recursivamente n veces antes de llegar al caso base, por lo que es
O(n), a menudo llamada lineal . - La segunda función se llama n-5 para cada vez, por lo que deducimos cinco de n antes de llamar a la función, pero n-5 también es
O(n). (En realidad llamado orden de n / 5 veces. Y, O (n / 5) = O (n)). - Esta función es log (n) base 5, por cada vez que lo dividimos por 5 antes de llamar a la función, su
O(log(n))(base 5), a menudo llamada logarítmica y más a menudo Big O, y el análisis de complejidad usa base 2 . - En el cuarto, es
O(2^n), o exponencial , ya que cada llamada a función se llama a sí misma dos veces a menos que haya sido recursada n veces. En cuanto a la última función, el ciclo for toma n / 2 ya que estamos aumentando en 2, y la recurrencia toma n-5 y dado que el ciclo for se llama recursivamente, por lo tanto, la complejidad temporal está en (n-5) * (n / 2) = (2n-10) * n = 2n ^ 2-10n, debido al comportamiento asintótico y al peor de los casos, o al límite superior que busca la gran O, solo estamos interesados en el término más grande, por lo que
O(n^2).Buena suerte en tus midterms;)
Tengo un término medio de informática mañana y necesito ayuda para determinar la complejidad de estas funciones recursivas. Sé cómo resolver casos simples, pero todavía estoy tratando de aprender a resolver estos casos más difíciles. Estos fueron solo algunos de los problemas de ejemplo que no pude resolver. Cualquier ayuda sería muy apreciada y sería de gran ayuda en mis estudios. ¡Gracias!
int recursiveFun1(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun1(n-1);
}
int recursiveFun2(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun2(n-5);
}
int recursiveFun3(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun3(n/5);
}
void recursiveFun4(int n, int m, int o)
{
if (n <= 0)
{
printf("%d, %d/n",m, o);
}
else
{
recursiveFun4(n-1, m+1, o);
recursiveFun4(n-1, m, o+1);
}
}
int recursiveFun5(int n)
{
for (i = 0; i < n; i += 2) {
// do something
}
if (n <= 0)
return 1;
else
return 1 + recursiveFun5(n-5);
}
Para el caso donde n <= 0 , T(n) = O(1) . Por lo tanto, la complejidad del tiempo dependerá de cuando n >= 0 .
Consideraremos el caso n >= 0 en la parte siguiente.
1.
T(n) = a + T(n - 1)
donde a es algo constante.
Por inducción:
T(n) = n * a + T(0) = n * a + b = O(n)
donde a, b son algunas constantes.
2.
T(n) = a + T(n - 5)
donde a es una constante
Por inducción:
T(n) = ceil(n / 5) * a + T(k) = ceil(n / 5) * a + b = O(n)
donde a, b son constantes yk <= 0
3.
T(n) = a + T(n / 5)
donde a es una constante
Por inducción:
T(n) = a * log5(n) + T(0) = a * log5(n) + b = O(log n)
donde a, b son algunas constantes
4.
T(n) = a + 2 * T(n - 1)
donde a es una constante
Por inducción:
T(n) = a + 2a + 4a + ... + 2^n * a + T(0) * 2 ^ n
= a * 2^(n+1) - a + b * 2 ^ n
= (2 * a + b) * 2 ^ n - a
= O(2 ^ n)
donde a, b son algunas constantes.
5.
T(n) = n / 2 + T(n - 5)
Podemos probar por inducción que T(5k) >= T(5k - d) donde d = 0, 1, 2, 3, 4
Escriba n = 5m - b (m, b son enteros; b = 0, 1, 2, 3, 4), luego m = (n + b) / 5 :
T(n) = T(5m - b) <= T(5m)
(En realidad, para ser más riguroso aquí, se debe definir una nueva función T''(n) tal que T''(5r - q) = T(5r) donde q = 0, 1, 2, 3, 4 Sabemos T(n) <= T''(n) como se demostró anteriormente. Cuando sabemos que T''(n) está en O(f) , lo que significa que existen constantes a, b de modo que T''(n) <= a * f(n) + b , podemos derivar que T(n) <= a * f(n) + b y por lo tanto T(n) está en O(f) . Este paso no es realmente necesario, pero es más fácil pensar cuando no tienes que lidiar con el resto).
Expansión T(5m) :
T(5m) = 5m / 2 + T(5m - 5)
= (5m / 2 + 5 / 2) * m / 2 + T(0)
= O(m ^ 2) = O(n ^ 2)
Por lo tanto, T(n) es O(n ^ 2) .
Una de las mejores maneras que encuentro para aproximar la complejidad del algoritmo recursivo es dibujando el árbol de recursión. Una vez que tienes el árbol recursivo:
Complexity = length of tree from root node to leaf node * number of leaf nodes
- La primera función tendrá una longitud de
ny un número de nodo de hoja1por lo que la complejidad serán*1 = n La segunda función tendrá la longitud de
n/5y la cantidad de nodos de hojas nuevamente1por lo que la complejidad serán/5 * 1 = n/5. Debe ser aproximado anPara la tercera función, dado que
nse divide por 5 en cada llamada recursiva, la longitud del árbol recursivo serálog(n)(base 5)y el número de nodos hoja nuevamente 1, por lo que la complejidad serálog(n)(base 5) * 1 = log(n)(base 5)Para la cuarta función, dado que cada nodo tendrá dos nodos secundarios, el número de nodos hoja será igual a
(2^n)y la longitud del árbol recursivo seránpor lo que la complejidad será(2^n) * n. Pero comones insignificante delante de(2^n), puede ignorarse y solo puede decirse que la complejidad es(2^n).Para la quinta función, hay dos elementos que introducen la complejidad. Complejidad introducida por la naturaleza recursiva de la función y complejidad introducida por
forloop en cada función. Al hacer el cálculo anterior, la complejidad introducida por la naturaleza recursiva de la función será~ ncomplejidad debido a for loopn. La complejidad total serán*n.
Nota: Esta es una manera rápida y sucia de calcular la complejidad (¡nada oficial!). Me encantaría escuchar comentarios sobre esto. Gracias.