Mañana tengo un examen intermedio de informática y necesito ayuda para determinar la complejidad de estas funciones recursivas. Sé cómo resolver casos simples, pero todavía estoy tratando de aprender cómo 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);
}
recursion
big-o
complexity-theory
Michael_19
fuente
fuente

Respuestas:
La complejidad del tiempo, en notación Big O, para cada función, está en orden numérico:
O(n), por lo que a menudo se llama lineal .O(n). (Realmente llamado orden de n / 5 veces. Y, O (n / 5) = O (n)).O(log(n))(base 5), a menudo llamada logarítmica y, con mayor frecuencia, la anotación Big O y el análisis de complejidad usan la base 2.O(2^n), o exponencial , ya que cada llamada de función se llama a sí misma dos veces a menos que se haya repetido n veces.En cuanto a la última función, el bucle for toma n / 2 ya que estamos aumentando en 2, y la recursión toma n-5 y dado que el bucle for se llama recursivamente, por lo tanto, la complejidad del tiempo está en (n-5) * (n / 2) = (2n-10) * n = 2n ^ 2- 10n, debido al comportamiento asintótico y las consideraciones del peor de los casos o el límite superior por el que se está esforzando la gran O, solo nos interesa el término más grande
O(n^2).Buena suerte en tus exámenes parciales;)
fuente
n/2iteraciones delforciclo, ¿por qué disminuir en 5 no daría lugar an/5llamadas recursivas? Esto aún resultaríaO(n^2)pero parece una explicación más intuitiva. ¿Por qué mezclar resta y división cuando son esenciales para hacer lo mismo?n/5non-5. Y finalmente, todo se reducirá aO(N^2).Para el caso en que
n <= 0,T(n) = O(1). Por lo tanto, la complejidad del tiempo dependerá de cuándon >= 0.Consideraremos el caso
n >= 0en la parte a continuación.1)
donde a es algo constante.
Por inducción:
donde a, b son algunas constantes.
2)
donde a es algo constante
Por inducción:
donde a, b son algunas constantes y k <= 0
3)
donde a es algo constante
Por inducción:
donde a, b son algunas constantes
4)
donde a es algo constante
Por inducción:
donde a, b son algunas constantes.
5)
donde n es alguna constante
Reescribe
n = 5q + rdonde q y r son enteros y r = 0, 1, 2, 3, 4Tenemos
q = (n - r) / 5, y desde r <5, podemos considerarlo una constante, por lo queq = O(n)Por inducción:
Como r <4, podemos encontrar alguna constante b para que
b >= T(r)fuente
Una de las mejores formas que encuentro para aproximar la complejidad del algoritmo recursivo es dibujar el árbol de recursividad. Una vez que tengas el árbol recursivo:
ny número de nodo hoja,1por lo que la complejidad serán*1 = nLa segunda función tendrá la longitud
n/5y el número de nodos hoja nuevamente,1por 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, ya que cada nodo tendrá dos nodos secundarios, el número de nodos hoja será igual
(2^n)y la longitud del árbol recursivo serántan compleja(2^n) * n. Pero comones insignificante frente a(2^n)esto, puede ser ignorado y solo se puede decir que la complejidad lo 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 el
forbucle en cada función. Haciendo el cálculo anterior, la complejidad introducida por la naturaleza recursiva de la función será~ ny la complejidad debida al bucle forn. Complejidad total serán*n.Nota: Esta es una forma rápida y sucia de calcular la complejidad (¡nada oficial!). Me encantaría recibir comentarios sobre esto. Gracias.
fuente
2^nentonces la altura del árbol debe sern, nolog n. La altura solo seríalog nsi senrepresenta el número total de nodos en el árbol. Pero no lo hace.Podemos demostrarlo matemáticamente, que es algo que me faltaba en las respuestas anteriores.
Puede ayudarte dramáticamente a entender cómo calcular cualquier método. Recomiendo leerlo de arriba a abajo para comprender completamente cómo hacerlo:
T(n) = T(n-1) + 1Significa que el tiempo que tarda el método en finalizar es igual al mismo método pero con n-1, que esT(n-1)y ahora agregamos+ 1porque es el tiempo que lleva completar las operaciones generales (exceptoT(n-1)). Ahora, vamos a encontrarT(n-1)la siguiente manera:T(n-1) = T(n-1-1) + 1. Parece que ahora podemos formar una función que nos puede dar algún tipo de repetición para que podamos entender completamente. Colocaremos el lado derecho delT(n-1) = ...lugar deT(n-1)dentro del métodoT(n) = ...que nos dará:T(n) = T(n-1-1) + 1 + 1que esT(n) = T(n-2) + 2o, en otras palabras, tenemos que encontrar nuestra faltak:T(n) = T(n-k) + k. El siguiente paso es tomarn-ky afirmar quen-k = 1porque al final de la recursión tomará exactamente O (1) cuandon<=0. De esta ecuación simple ahora lo sabemosk = n - 1. Coloquemosken nuestro método final:T(n) = T(n-k) + kque nos dará:T(n) = 1 + n - 1cuál es exactamentenoO(n).O(n).T(n) = T(n/5) + 1como antes, el tiempo para que este método termine es igual al tiempo del mismo método, pero con eln/5cual está limitadoT(n/5). EncontremosT(n/5)como en 1:T(n/5) = T(n/5/5) + 1que esT(n/5) = T(n/5^2) + 1. Vamos a caboT(n/5)en el interiorT(n)para el cálculo final:T(n) = T(n/5^k) + k. De nuevo como antes,n/5^k = 1que esn = 5^kexactamente como preguntar qué en potencia de 5 nos dará n, la respuesta eslog5n = k(log de base 5). Coloquemos nuestros hallazgos de laT(n) = T(n/5^k) + ksiguiente manera:T(n) = 1 + lognque esO(logn)T(n) = 2T(n-1) + 1lo que tenemos aquí es básicamente lo mismo que antes, pero esta vez estamos invocando el método recursivamente 2 veces, por lo que lo multiplicamos por 2. VeamosT(n-1) = 2T(n-1-1) + 1cuál esT(n-1) = 2T(n-2) + 1. Nuestro próximo lugar como antes, ubiquemos nuestro hallazgo:T(n) = 2(2T(n-2)) + 1 + 1que es loT(n) = 2^2T(n-2) + 2que nos daT(n) = 2^kT(n-k) + k. Encontremoskreclamando lo quen-k = 1esk = n - 1. Coloquemos de laksiguiente manera:T(n) = 2^(n-1) + n - 1que es aproximadamenteO(2^n)T(n) = T(n-5) + n + 1Es casi lo mismo que 4 pero ahora agregamosnporque tenemos unforbucle. VeamosT(n-5) = T(n-5-5) + n + 1cuál esT(n-5) = T(n - 2*5) + n + 1. Vamos a colocarlo:T(n) = T(n-2*5) + n + n + 1 + 1)cuál esT(n) = T(n-2*5) + 2n + 2)y para k:T(n) = T(n-k*5) + kn + k)nuevamente:n-5k = 1cuál esn = 5k + 1eso es más o menosn = k. Esto nos dará:T(n) = T(0) + n^2 + nque es más o menosO(n^2).Ahora recomiendo leer el resto de las respuestas, que ahora le darán una mejor perspectiva. Buena suerte ganando esas grandes O :)
fuente
La clave aquí es visualizar el árbol de llamadas. Una vez hecho eso, la complejidad es:
El último término se puede calcular de la misma manera que lo hacemos para una función iterativa normal.
En cambio, los nodos totales de un árbol completo se calculan como
Donde C es el número de hijos de cada nodo y L es el número de niveles del árbol (raíz incluida).
Es fácil visualizar el árbol. Comience desde la primera llamada (nodo raíz) y luego dibuje un número de hijos igual al número de llamadas recursivas en la función. También es útil escribir el parámetro pasado a la sub-llamada como "valor del nodo".
Entonces, en los ejemplos anteriores:
fuente