Complexité d'algorithmes
Lucie22
-
KX Messages postés 16761 Date d'inscription Statut Modérateur Dernière intervention -
KX Messages postés 16761 Date d'inscription Statut Modérateur Dernière intervention -
Bonsoir !
J'ai du mal à comprendre la notion de complexité d'algorithmes. Par exemple, ici, je dois trouver la complexité des 4 algo' ci-dessous. Le premier n'étant pas récursif, je pense avoir trouvé qu'il s'agit d'une complexité O(n). Par contre, pour les 3 autres, je ne sais pas par où commencer...
En cours, j'ai vu la méthode des arbres récursifs à partir d'une expression T(n) donnée. Or, ici, je n'arrive pas à trouver l'expression de T(n) à partir des algo...
J'ai donc essayer de trouver leur complexité un peu "à l'oeil" en essayant de comprendre comment fonctionnait chaque algorithme et j'en suis arrivée à trouver une complexité en O(n) pour le troisième, et en O(log(n)) pour les 2 autres.
Quelqu'un pourrait-il me valider ces résultats ?
Et, le cas échéant, m'expliquer comment je suis censé procéder pour trouver la complexité d'algo récursifs ?
J'ai du mal à comprendre la notion de complexité d'algorithmes. Par exemple, ici, je dois trouver la complexité des 4 algo' ci-dessous. Le premier n'étant pas récursif, je pense avoir trouvé qu'il s'agit d'une complexité O(n). Par contre, pour les 3 autres, je ne sais pas par où commencer...
En cours, j'ai vu la méthode des arbres récursifs à partir d'une expression T(n) donnée. Or, ici, je n'arrive pas à trouver l'expression de T(n) à partir des algo...
J'ai donc essayer de trouver leur complexité un peu "à l'oeil" en essayant de comprendre comment fonctionnait chaque algorithme et j'en suis arrivée à trouver une complexité en O(n) pour le troisième, et en O(log(n)) pour les 2 autres.
Quelqu'un pourrait-il me valider ces résultats ?
Et, le cas échéant, m'expliquer comment je suis censé procéder pour trouver la complexité d'algo récursifs ?
public class Math{ public static int multiIter(int x, int y){ int sum = 0; for (int i=0; i<y; i++) { sum += x; } return sum; } public static int multiRec(int x, int y){ if (x == 0){ return 0; } else if (x%2 == 0){ return 2*multiRec(x/2, y); } else{ return 2*multiRec((x-1)/2, y)+y; } } public static int puissanceRec(int x, int n){ if (n==0){ return 1; } else{ return puissanceRec(x,n-1)*x; } } public static int exponentiationRapide(int x, int n){ if (n==0){ return 1; } else if (n%2 == 0){ return exponentiationRapide(x*x, n/2); } else{ return exponentiationRapide(x*x, (n-1)/2)*x; } } }
Configuration: Windows / Opera 83.0.4254.70
A voir également:
- Complexité d'algorithmes
- Complexite et np completude - Forum Programmation
- Algorithmes maximum et minimum - Forum Algorithmes / Méthodes
- Ce mot de passe ne répond pas aux critères de longueur, de complexité, de date ou d'historique de la stratégie de mot de passe de votre entreprise. - Forum Réseau
- Exos Algorithmes BTS IG corrigés ✓ - Forum Études / Formation High-Tech
- Modifier stratégie de mot de passe - Forum Windows serveur
1 réponse
Bonjour,
"J'ai du mal à comprendre la notion de complexité d'algorithmes."
Pour faire simple, il s'agit d'estimer le nombre de ressources que ton programme devra traiter. Dans ton cas il s'agit de la complexité en temps de calcul, mais cela pourrait aussi être une complexité en mémoire.
Cela permet d'anticiper théoriquement le comportement du programme quand on augmente le nombre de données à traiter. On peut ainsi comparer deux algorithmes entre eux et choisir lequel sera le plus adapté, par exemple le plus rapide, le moins gourmand en mémoire, ou un compromis entre les deux.
"Le premier n'étant pas récursif, je pense avoir trouvé qu'il s'agit d'une complexité O(n) [...] j'en suis arrivée à trouver une complexité en O(n) pour le troisième, et en O(log(n)) pour les 2 autres."
Je suis d'accord avec les résultats. Toutefois, au niveau du raisonnement dire qu'il est en O(n) car il n'est pas récursif est faux, on pourrait très bien réécrire les autres algorithmes en enlevant leur récursivité, ils conserveraient quand même leur complexité logarithmique en temps.
Remarque : enlever la récursivité de l'algorithme diminuerait cependant la complexité en mémoire.
"comment je suis censé procéder pour trouver la complexité d'algo récursifs ?"
On peut le faire mathématiquement, en se servant d'outils simples tels que les suites, le raisonnement par récurrence, ou plus avancés comme la comparaison asymptotique, d'où viennent notamment les notation de Landeau comme O(n)
Exemple, avec multiRec
Si x = 0 : f(x) = 1 => on est passé une fois dans la méthode
Si x > 0 et x%2 == 0 : f(x)= 1 + f(x/2) => on passe une fois dans la méthode, plus le nombre de fois pour f(x/2)
Si x > 0 et x%2 != 0 : f(x)= 1 + f((x-1)/2) = 1 + f(x/2) => on a donc un seul cas pour x > 0
Soit x=2^n : f(x)=1+f(x/2) <=> f(2^n)=1+f(2^(n-1))=2+f(2^(n-2))=3+f(2^(n-3))= ... = n + f(2^0)
Donc f(2^n) = O(n) <=> f(x) = O(ln(x))
Pour résumer :
"J'ai du mal à comprendre la notion de complexité d'algorithmes."
Pour faire simple, il s'agit d'estimer le nombre de ressources que ton programme devra traiter. Dans ton cas il s'agit de la complexité en temps de calcul, mais cela pourrait aussi être une complexité en mémoire.
Cela permet d'anticiper théoriquement le comportement du programme quand on augmente le nombre de données à traiter. On peut ainsi comparer deux algorithmes entre eux et choisir lequel sera le plus adapté, par exemple le plus rapide, le moins gourmand en mémoire, ou un compromis entre les deux.
"Le premier n'étant pas récursif, je pense avoir trouvé qu'il s'agit d'une complexité O(n) [...] j'en suis arrivée à trouver une complexité en O(n) pour le troisième, et en O(log(n)) pour les 2 autres."
Je suis d'accord avec les résultats. Toutefois, au niveau du raisonnement dire qu'il est en O(n) car il n'est pas récursif est faux, on pourrait très bien réécrire les autres algorithmes en enlevant leur récursivité, ils conserveraient quand même leur complexité logarithmique en temps.
Remarque : enlever la récursivité de l'algorithme diminuerait cependant la complexité en mémoire.
"comment je suis censé procéder pour trouver la complexité d'algo récursifs ?"
On peut le faire mathématiquement, en se servant d'outils simples tels que les suites, le raisonnement par récurrence, ou plus avancés comme la comparaison asymptotique, d'où viennent notamment les notation de Landeau comme O(n)
Exemple, avec multiRec
Si x = 0 : f(x) = 1 => on est passé une fois dans la méthode
Si x > 0 et x%2 == 0 : f(x)= 1 + f(x/2) => on passe une fois dans la méthode, plus le nombre de fois pour f(x/2)
Si x > 0 et x%2 != 0 : f(x)= 1 + f((x-1)/2) = 1 + f(x/2) => on a donc un seul cas pour x > 0
Soit x=2^n : f(x)=1+f(x/2) <=> f(2^n)=1+f(2^(n-1))=2+f(2^(n-2))=3+f(2^(n-3))= ... = n + f(2^0)
Donc f(2^n) = O(n) <=> f(x) = O(ln(x))
Pour résumer :
- multiIter : O(n) en temps, O(1) en mémoire
- multiRec : O(ln(n)) en temps, O(ln(n)) en mémoire
- puissanceRec : O(n) en temps, O(n) en mémoire
- exponentiationRapide : O(ln(n)) en temps, O(ln(n)) en mémoire