- 8 -
Complexité algorithmique
• De quoi dépend le temps d'exécution d'un programme ? Surtout du nombre
d'instructions machine effectivement exécutées, lui-même déterminé par :
... les données à traiter, surtout le volume de ces données
... le code source, surtout les algorithmes utilisés
• Pour évaluer l'efficacité en temps de calcul d'un algorithme donné, on veut
estimer le nombre d'instructions exécutées en fonction du volume des données
• Exemple (à discuter) :
public class Pg1 {
public static void main(String[] args) {
printTable(7); // 1x (?)
}
private static void printTable(int n) {
int i,j; // 1x (?)
for(i=1; i<=n; i++) { // 1x; 8x; 7x
for(j=1; j<=n; j++) // 7x; 56x; 49x
System.out.print(" " + i*j); // 49x; 49x; 49x
System.out.println(); // 7x
}
} // total = 284 instructions
} // (plus le "détail" (!!) de print)
// 5n2 + 5n + 4 ® dépend de n2
n2
- 9 -
Compter les instructions à exécuter
• On s'intéresse au temps de calcul. On suppose qu'il dépend surtout du
nombre d'instructions à exécuter
• Soit n défini comme la "taille du problème" (p. ex. la taille du tableau à trier)
• Pour simplifier la discussion, on supposera que les "instructions élémentaires" sont
toutes équivalentes en temps de calcul
• Comment calculer le nombre I(n) d'instructions du programme en fct de n
• Séquences d'instructions : I(n) = Ia(n) + Ib(n) + Ic(n)
{
a;
b;
c;
}
• Boucles, où a est le nbre d'itérations (de passages effectués)
while(test) { I(n) = (a+1) *(Itest (n))
corps; + a *(Icorps(n))
}
• Appels de méthodes I(n) = 1 + Icorps de la méthode(n)
meth();
- 10 -
Ordre de grandeur, notation O(...)
• Le nombre exact d'instructions est peu informatif
On cherche à caractériser la croissance de la fonction quand n varie
• Pour de grandes valeurs de n, une fonction linéaire finit toujours par être
inférieure à une fonction quadratique
• (5n2+n) et (4n2+3n) sont de la même famille (fonctions quadratiques)
(50n+8) est d'une "meilleure" famille (fonction linéaire)
• Ce qui compte, c'est donc la partie dominante ! On ne retient que le terme de
plus haut degré, et on ignore les coefficents constants
• Exemple : Nombre d'instruction I(n) = 5n2 + 3n + 127
Partie dominante I(n) est en O(n2)
• On dit que I(n) est du même ordre de grandeur que f(n) et on note
I(n) est en O(f(n)) si $ c, n0 tq " n ³ n0, I(n) £ cf(n)
"… finit par être majoré par un multiple de …"
• Exemples :
3n3 + 2n + 10 est en O(n3)
2n + 300n200 est en O(2n)
log10(n) + 212 est en O(ln(n))
0.0001n + log(n) est en O(n)
• Sur un ordinateur plus puissant, un algorithme quadratique s'exécutera
peut-être 5 fois plus rapidement.... mais il restera quadratique !
- 11 -
• Evolution de quelques fonctions de complexité pour des tailles de problèmes...
petites plus grandes
- 12 -
Estimation ou vérification empirique
• Soit un programme P qui est censé dépendre du nombre n de données
• On peut lancer P avec des données différentes (10, 50, 100, 1000),
et mesurer les temps de calcul (T10, T50, T100, T1000)
• Pour savoir si Tn est en O(f(n)), on teste si (Tn / f(n)) semble constant
• Exemple : Soit Tn = 3n2 +48n +131; T
n
est donc en O(n2)
Pour m suffisamment grand, (Tm / m2) @ 3
• Mesurer un intervalle de temps en Java :
// in class System : static long currentTimeMillis()
long ta, tb;
ta = System.currentTimeMillis();
doSomething();
tb = System.currentTimeMillis();
System.out.println("Elapsed time = " + (tb-ta));
• Granularité (ms, ns) : il s'en passe des choses, en une milliseconde....
• Quand un programme fait des entrées/sorties, l'hypothèse que toutes les
instructions se valent n'est vraiment pas vérifiée
• L'analyse de complexité peut porter sur n'importe quelle ressource (p. ex
RAM), pas seulement le temps de calcul CPU.
1 / 14 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans l'interface ou les textes ? Ou savez-vous comment améliorer l'interface utilisateur de StudyLib ? N'hésitez pas à envoyer vos suggestions. C'est très important pour nous!