par Dominique Lefebvre » 18 Nov 2006, 18:18
Bon, je vais essayer d'éclairer, du moins commencer à éclairer la notion de complexité.
Tout d'abord, il faut bien distinguer la complexité d'un algorithme de celle d'un problème (que je n'aborderai pas ici). La complexité d'un problème est la complexité du meilleur algorithme connu pour résoudre ce problème. Et donc, la complexité d'un problème est susceptible d'évoluer avec nos connaissances en algorithmique...
Il faut se rappeller qu'un algorithme présente deux caractéristiques fondamentales:
- le temps de calcul nécessaire pour le dérouler. Ce temps dépend du nombre d'opérations à effectuer et de la nature des opérations. Une addition est beaucoup plus rapidement exécutée qu'une multiplication... (rapport de 1 à 3 ou 4 au moins!). La limite tient donc dans le temps disponible! Et donc, pour un ordianteur, aussi de sa rapidité (fréquence CPU, architecture parallèle, bus inter-CPU, mémoire, etc.)
- la quantité de données à manipuler par l'algorithme. Cette quantité est limitée par la mémoire de travail de l'ordinateur, si on déroule l'algo. sur un ordinateur.
Donc, pour évaluer la complexité d'un algorithme, on cherche à mettre en évidence:
- le nombre d'opérations fondamentales (+, x) dans l'algo,
- une évaluation de la taille des données.
Il s'agit bien d'établir un ordre de grandeur de ces informations, dans le cas le plus défavorable du déroulement.
Il faut noter que la complexité d'un algo n'est pas lié au langage, au compilateur ou à la machine sur laquelle on l'exécute. C'est une caractéristique de l'algo.
Pour décrire la complexité, on utilise la notation O(), qui se lit "grand O".
On l'exprime en fonction de n, le nombre de données traitées par l'algorithme. En simplifiant à l'extrème, c'est une fonction qui donne un ordre de grandeur asymptotique de la complexité d'un algo.
Par exemple, on dira qu'un algo est de complexité O(n^2) lorsque on peut majorer le nombre d'opérations à n^2, dans le pire des cas.
Il existe des algos de complexité O(n), O(nlogn), O(2^n) et les pires O(n^n). Il est évident qu'un algo O(nlogn) vaut bien mieux qu'un algo de 2^n.
Exemple célèbre de réduction de complexité par la recherche: l'algo de calcul d'une transformée de Fourier. le calcul classique donne une complexité de O(n^2). Le calcul par l'algo de FFT donne une complexité de O(nlogn) où log est le log de base 2. C'est considérable!! Pour un PC qui travaille à 1 MFlop (10^6 opérations en virgule flottante par seconde), et pour n = 1 024 (c'est peu...), la différence va de 1 seconde pour O(nlogn) à plusieurs heures pour O(n^2)....
Une dernière chose: chercher la complexité d'un algo. sert surtout à comparer l'efficacité de plusieurs algos et choisir le meilleur...