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/2
iteraciones delfor
ciclo, ¿por qué disminuir en 5 no daría lugar an/5
llamadas 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/5
non-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 >= 0
en 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 + r
donde 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:
n
y número de nodo hoja,1
por lo que la complejidad serán*1 = n
La segunda función tendrá la longitud
n/5
y el número de nodos hoja nuevamente,1
por lo que la complejidad serán/5 * 1 = n/5
. Debe ser aproximado an
Para la tercera función, dado que
n
se 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án
tan compleja(2^n) * n
. Pero comon
es 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
for
bucle en cada función. Haciendo el cálculo anterior, la complejidad introducida por la naturaleza recursiva de la función será~ n
y 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^n
entonces la altura del árbol debe sern
, nolog n
. La altura solo seríalog n
si sen
representa 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) + 1
Significa 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+ 1
porque 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 + 1
que esT(n) = T(n-2) + 2
o, en otras palabras, tenemos que encontrar nuestra faltak
:T(n) = T(n-k) + k
. El siguiente paso es tomarn-k
y afirmar quen-k = 1
porque al final de la recursión tomará exactamente O (1) cuandon<=0
. De esta ecuación simple ahora lo sabemosk = n - 1
. Coloquemosk
en nuestro método final:T(n) = T(n-k) + k
que nos dará:T(n) = 1 + n - 1
cuál es exactamenten
oO(n)
.O(n)
.T(n) = T(n/5) + 1
como antes, el tiempo para que este método termine es igual al tiempo del mismo método, pero con eln/5
cual está limitadoT(n/5)
. EncontremosT(n/5)
como en 1:T(n/5) = T(n/5/5) + 1
que 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 = 1
que esn = 5^k
exactamente 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) + k
siguiente manera:T(n) = 1 + logn
que esO(logn)
T(n) = 2T(n-1) + 1
lo 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) + 1
cuál esT(n-1) = 2T(n-2) + 1
. Nuestro próximo lugar como antes, ubiquemos nuestro hallazgo:T(n) = 2(2T(n-2)) + 1 + 1
que es loT(n) = 2^2T(n-2) + 2
que nos daT(n) = 2^kT(n-k) + k
. Encontremosk
reclamando lo quen-k = 1
esk = n - 1
. Coloquemos de lak
siguiente manera:T(n) = 2^(n-1) + n - 1
que es aproximadamenteO(2^n)
T(n) = T(n-5) + n + 1
Es casi lo mismo que 4 pero ahora agregamosn
porque tenemos unfor
bucle. VeamosT(n-5) = T(n-5-5) + n + 1
cuá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 = 1
cuál esn = 5k + 1
eso es más o menosn = k
. Esto nos dará:T(n) = T(0) + n^2 + n
que 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