J'ai un Computer Science Midterm demain et j'ai besoin d'aide pour déterminer la complexité de ces fonctions récursives. Je sais comment résoudre des cas simples, mais j'essaie toujours d'apprendre à résoudre ces cas plus difficiles. Ce ne sont que quelques-uns des exemples de problèmes que je n'ai pas pu comprendre. Toute aide serait très appréciée et aiderait grandement dans mes études, merci!
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
la source
la source
Réponses:
La complexité temporelle, en notation Big O, pour chaque fonction, est dans l'ordre numérique:
O(n)
, souvent appelé linéaire .O(n)
. (Appelé en fait n / 5 fois. Et, O (n / 5) = O (n)).O(log(n))
(base 5), souvent appelée logarithmique et le plus souvent la notation Big O et l'analyse de complexité utilisent la base 2.O(2^n)
, ou exponentiel , puisque chaque appel de fonction s'appelle deux fois sauf s'il a été récursé n fois.Comme pour la dernière fonction, la boucle for prend n / 2 puisque nous augmentons de 2, et la récursion prend n-5 et puisque la boucle for est appelée récursivement donc la complexité temporelle est en (n-5) * (n / 2) = (2n-10) * n = 2n ^ 2- 10n, en raison du comportement asymptotique et des considérations du pire scénario ou de la limite supérieure que le grand O cherche, nous ne sommes intéressés que par le plus grand terme
O(n^2)
.Bonne chance à mi-parcours;)
la source
n/2
itérations de lafor
boucle, pourquoi la décrémentation de 5 n'entraînerait-elle pas d'n/5
appels récursifs? Cela entraînerait toujoursO(n^2)
mais semble une explication plus intuitive. Pourquoi mélanger la soustraction et la division quand elles sont essentielles en faisant la même chose?n/5
pas l' êtren-5
. Et finalement, tout se résumera àO(N^2)
.Pour le cas où
n <= 0
,T(n) = O(1)
. Par conséquent, la complexité temporelle dépendra du momentn >= 0
.Nous examinerons le cas
n >= 0
dans la partie ci-dessous.1.
où a est une constante.
Par induction:
où a, b sont des constantes.
2.
où a est une constante
Par induction:
où a, b sont des constantes et k <= 0
3.
où a est une constante
Par induction:
où a, b sont des constantes
4.
où a est une constante
Par induction:
où a, b sont des constantes.
5.
où n est une constante
Réécrire
n = 5q + r
où q et r sont des nombres entiers et r = 0, 1, 2, 3, 4Nous avons
q = (n - r) / 5
, et puisque r <5, nous pouvons le considérer comme une constante, doncq = O(n)
Par induction:
Puisque r <4, nous pouvons trouver une constante b de sorte que
b >= T(r)
la source
L'un des meilleurs moyens que je trouve pour approximer la complexité de l'algorithme récursif est de dessiner l'arbre de récursivité. Une fois que vous avez l'arborescence récursive:
n
et le nombre de nœuds feuilles,1
donc la complexité seran*1 = n
La deuxième fonction aura à nouveau la longueur
n/5
et le nombre de nœuds feuilles, de1
sorte que la complexité seran/5 * 1 = n/5
. Il devrait être approximé àn
Pour la troisième fonction, étant donné qu'elle
n
est divisée par 5 à chaque appel récursif, la longueur de l'arbre récursif seralog(n)(base 5)
et le nombre de nœuds foliaires à nouveau 1 donc la complexité seralog(n)(base 5) * 1 = log(n)(base 5)
Pour la quatrième fonction, puisque chaque nœud aura deux nœuds enfants, le nombre de nœuds feuilles sera égal à
(2^n)
et la longueur de l'arbre récursif seran
telle que la complexité sera(2^n) * n
. Mais comme iln
est insignifiant devant(2^n)
, il peut être ignoré et la complexité ne peut qu’être dite(2^n)
.Pour la cinquième fonction, deux éléments introduisent la complexité. Complexité introduite par la nature récursive de la fonction et complexité introduite par la
for
boucle dans chaque fonction. En faisant le calcul ci-dessus, la complexité introduite par la nature récursive de la fonction sera~ n
et la complexité due à la bouclen
. La complexité totale seran*n
.Remarque: Il s'agit d'un moyen rapide et sale de calculer la complexité (rien d'officiel!). J'adorerais entendre des commentaires à ce sujet. Merci.
la source
2^n
alors la hauteur de l'arbre doit êtren
, nonlog n
. La hauteur ne serait quelog n
si ellen
représentait le nombre total de nœuds dans l'arbre. Mais ce n'est pas le cas.Nous pouvons le prouver mathématiquement, ce qui me manquait dans les réponses ci-dessus.
Il peut considérablement vous aider à comprendre comment calculer n'importe quelle méthode. Je recommande de le lire de haut en bas pour bien comprendre comment le faire:
T(n) = T(n-1) + 1
Cela signifie que le temps qu'il faut pour que la méthode se termine est égal à la même méthode mais avec n-1 qui estT(n-1)
et nous ajoutons maintenant+ 1
parce que c'est le temps qu'il faut pour que les opérations générales soient terminées (saufT(n-1)
). Maintenant, nous allons trouverT(n-1)
comme suit:T(n-1) = T(n-1-1) + 1
. Il semble que nous pouvons maintenant former une fonction qui peut nous donner une sorte de répétition afin que nous puissions comprendre pleinement. Nous allons placer le côté droit de laT(n-1) = ...
place de l'T(n-1)
intérieur de la méthodeT(n) = ...
qui nous donnera:T(n) = T(n-1-1) + 1 + 1
qui est -T(n) = T(n-2) + 2
à - dire que nous devons trouver notre manquek
:T(n) = T(n-k) + k
. L'étape suivante consiste à prendren-k
et à affirmer que,n-k = 1
car à la fin de la récursivité, il faudra exactement O (1) lorsquen<=0
. De cette simple équation, nous le savons maintenantk = n - 1
. Mettonsk
dans notre méthode finale:T(n) = T(n-k) + k
qui nous donnera:T(n) = 1 + n - 1
qui est exactementn
ouO(n)
.O(n)
.T(n) = T(n/5) + 1
comme précédemment, le temps de fin de cette méthode est égal au temps de la même méthode, maisn/5
c'est pourquoi elle est limitéeT(n/5)
. TrouvonsT(n/5)
comme en 1:T(n/5) = T(n/5/5) + 1
qui estT(n/5) = T(n/5^2) + 1
. Place LetT(n/5)
intérieurT(n)
pour le calcul final:T(n) = T(n/5^k) + k
. Encore une fois comme précédemment,n/5^k = 1
qui estn = 5^k
exactement comme demander ce qui au pouvoir de 5, nous donnera n, la réponse estlog5n = k
(log de base 5). Plaçons nos conclusionsT(n) = T(n/5^k) + k
comme suit:T(n) = 1 + logn
qui estO(logn)
T(n) = 2T(n-1) + 1
ce que nous avons ici est fondamentalement le même qu'avant mais cette fois nous invoquons la méthode récursivement 2 fois donc nous la multiplions par 2. Voyons ceT(n-1) = 2T(n-1-1) + 1
qui estT(n-1) = 2T(n-2) + 1
. Notre prochain endroit comme avant, plaçons notre conclusion:T(n) = 2(2T(n-2)) + 1 + 1
quiT(n) = 2^2T(n-2) + 2
nous donneT(n) = 2^kT(n-k) + k
. Trouvonsk
en revendiquant cen-k = 1
qui estk = n - 1
. Mettonsk
comme suit:T(n) = 2^(n-1) + n - 1
ce qui est à peu prèsO(2^n)
T(n) = T(n-5) + n + 1
C'est presque la même chose que 4 mais maintenant nous ajoutonsn
parce que nous avons unefor
boucle. TrouvonsT(n-5) = T(n-5-5) + n + 1
lequel estT(n-5) = T(n - 2*5) + n + 1
. Mettons-le:T(n) = T(n-2*5) + n + n + 1 + 1)
qui estT(n) = T(n-2*5) + 2n + 2)
et pour le k:T(n) = T(n-k*5) + kn + k)
encore:n-5k = 1
quin = 5k + 1
est à peu prèsn = k
. Cela nous donnera:T(n) = T(0) + n^2 + n
ce qui est à peu prèsO(n^2)
.Je recommande maintenant de lire le reste des réponses qui, maintenant, vous donneront une meilleure perspective. Bonne chance pour gagner ces gros O :)
la source
La clé ici est de visualiser l'arborescence des appels. Une fois cela fait, la complexité est:
ce dernier terme peut être calculé de la même manière que pour une fonction itérative normale.
Au lieu de cela, le nombre total de nœuds d'une arborescence complète est calculé comme
Où C est le nombre d'enfants de chaque nœud et L est le nombre de niveaux de l'arbre (racine incluse).
Il est facile de visualiser l'arbre. Commencez par le premier appel (nœud racine) puis dessinez un nombre d'enfants identique au nombre d'appels récursifs dans la fonction. Il est également utile d'écrire le paramètre passé au sous-appel comme "valeur du nœud".
Donc, dans les exemples ci-dessus:
la source