Complexité

Le calcul de la complexité d’un algorithme permet de mesurer sa performance. Il existe deux types de complexité :

  • complexité spatiale : permet de quantifier l’utilisation de la mémoire
  • complexité temporelle : permet de quantifier la vitesse d’exécution

Complexité temporelle

Définition

La complexité, ou le temps d’exécution, d’un programme \(P\) (fonction ou procédure) est le nombre d’opérations élémentaires (addition, multiplication, affectation, test, etc…) nécessaires à l’exécution de \(P\).

Lorsque cette complexité dépend de plusieurs paramètres \(n\) et \(m\), on dira que \(P\) a une complexité en \(\mathcal{O}(\Phi(n,m))\), lorsqu’il existe trois constantes \(A, n_0\) et \(m_0\) telles que la complexité de \(P\) soit inférieure ou égale à \(A\times \Phi(n,m)\), pour tout \(n > n_0\) et \(m > m_0\).

L’objectif d’un calcul de complexité algorithmique temporelle est de pouvoir comparer l’efficacité d’algorithmes résolvant le même problème. Dans une situation donnée, cela permet donc d’établir lequel des algorithmes disponibles est le plus optimal.

Pour des données volumineuses la différence entre les durées d’exécution de deux algorithmes ayant la même finalité peut être de l’ordre de plusieurs jours !

Réaliser un calcul de complexité en temps revient à compter le nombre d’opérations élémentaires (affectation, calcul arithmétique ou logique, comparaison…) effectuées par l’algorithme.

Puisqu’il s’agit seulement de comparer des algorithmes, les règles de ce calcul doivent être indépendantes :

  • du langage de programmation utilisé ;
  • du processeur de l’ordinateur sur lequel sera exécuté le code ;
  • de l’éventuel compilateur employé.

Par soucis de simplicité, on fera l’hypothèse que toutes les opérations élémentaires sont à égalité de coût, soit 1 « unité » de temps.

Exemple : a = b * 3 : 1 multiplication + 1 affectation = 2 « unités »

La complexité en temps d’un algorithme sera exprimé par une fonction, notée \(T\) (pour Time), qui dépend :

  • de la taille des données passées en paramètres : plus ces données seront volumineuses, plus il faudra d’opérations élémentaires pour les traiter.
    On notera \(n\) le nombre de données à traiter.
  • de la donnée en elle même, de la façon dont sont réparties les différentes valeurs qui la constituent.
    par exemple, si on effectue une recherche séquentielle d’un élément dans une liste non triée, on parcourt un par un les éléments jusqu’à trouver, ou pas, celui recherché. Ce parcours peut s’arrêter dès le début si le premier élément est « le bon ». Mais on peut également être amené à parcourir la liste en entier si l’élément cherché est en dernière position, ou même n’y figure pas.

Cette remarque nous conduit à préciser un peu notre définition de la complexité en temps. En toute rigueur, on peut en effet distinguer deux formes de complexité en temps :

  • la complexité dans le meilleur des cas : c’est la situation la plus favorable,
    par exemple : recherche d’un élément situé à la première position d’une liste
  • la complexité dans le pire des cas : c’est la situation la plus défavorable,
    par exemple : recherche d’un élément dans une liste alors qu’il n’y figure pas

On calculera le plus souvent la complexité dans le pire des cas, car elle est la plus pertinente. Il vaut mieux en effet toujours envisager le pire.

 

Ordre de grandeur

Pour comparer des algorithmes, il n’est pas nécessaire d’utiliser la fonction \(T\), mais seulement l’ordre de grandeur asymptotique, noté \(O\) (« grand O »).

Une fonction \(T(n)\) est en \(O\left(f(n)\right)\) (« en grand O de f(n)« ) si :

\(\exists n_0\in\mathbb{N}, \exists c\in\mathbb{R}, \forall n\geq n_0 : |T(n)|\leq c|f(n)|\)

Autrement dit :

\(T(n)\) est en \(O\left(f(n)\right)\) s’il existe un seuil \(n_0\) à partir duquel la fonction \(T\) est toujours dominée par la fonction \(f\), à une constante multiplicative fixée \(c\) près.

Exemples :

  • \(T_1(n)=7=O(1)\)
  • \(T_2(n)=12n+5=O(n)\)
  • \(T_3(n)=4n^2+2n+6=O(n^2)\)
  • \(T_4(n)=2+(n-1)\times 5=O(n)\)

Classes de complexité

O Type de complexité
\(O(1)\) constante
\(O(log(n))\) logarithmique
\(O(n)\) linéaire
\(O(n×log(n))\) quasi-linéaire
\(O(n^2)\) quadratique
\(O(n^3)\) cubique
\(O(2^n)\) exponentielle
\(O(n!)\) factorielle

 

Exemple de calcul de complexité

def factorielle(n):
   fact = 1
   i = 2

   while i <= n:
      fact = fact * i
      i = i + 1
   return fact
.

affectation : 1
affectation : 1
itérations : au plus n − 1
   comparaison : 1
   multiplication + affectation : 2
   addition + affectation : 2
\(T(n)=2+5(n-1)=O(n)\)

 


Exercices

Exercices

Calculer la complexité des fonctions ci-dessous :

def conversion(n):
    h = n // 3600
    m = (n - 3600*h) // 60
    s = n % 60
    return h,m,s

 

def puissanceMoinsUn(n):
   if n%2==0:
      res = 1
   else:
      res = -1
   return res

 

def sommeEntiers(n):
    somme = 0
    for i in range(n+1):
        somme += i
    return somme

 

def factorielle(n):
   fact = 1 
   i = 2
   while i <= n:
      fact = fact * i
      i = i + 1
   return fact

 

def triSelection(l):
    for i in range(len(l)-1):
        indMini=i
        for j in range(i+1,len(l)):
            if l[j]<l[indMini]:
                indMini=j
        l[i],l[indMini]=l[indMini],l[i]

 

 

sources : https://gargantua.polytechnique.fr/siatel-web/linkto/mICYYYTEsXY6
http://igm.univ-mlv.fr/~alabarre/teaching/struct/poly-m1103.pdf
https://www.supinfo.com/cours/2ADS/chapitres/01-notion-complexite-algorithmique
http://igm.univ-mlv.fr/~alabarre/teaching/struct/01-complexite-handout.pdf

 


Ce contenu est réservé aux membres uniquement. Veuillez vous %connecter%.

 

Ressources

https://www.supinfo.com/cours/2ADS/chapitres/01-notion-complexite-algorithmique

 

 

Vous aimerez aussi...

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *