Vous êtes sur la page 1sur 6

CPGE OUJDA MPSI

Calculs de complexité

Étudier la complexité (en temps) d’une fonction f , c’est déterminer son temps d’exécution Tf
en fonction de la taille des données. En pratique :
• Ce temps d’exécution est compté en nombre d’opérations élémentaires (à préciser
suivant les cas) ;
• La taille des données est également à préciser, pour une liste L c’est sa longueur ;
• On se contente d’un ordre de grandeur en utilisant la notation O.
On obtient souvent des relations du type T f (n)  O(n), T f (n)  O(n ln(n)), etc.
L’intérêt de pouvoir comparer la complexité de différents algorithmes c’est pour ne conserver que les
plus efficaces. Prenons par exemple l'algorithme qui lit un tableau et teste chacune de ses cases : si
le tableau a n cases, l'algorithme effectuera n tests ! On dit que sa complexité est en O(n).

L'écriture O

O(n) se lit "grand O de n". Cette notation mathématique signifie que la complexité de l'algorithme est
proportionnelle à n (le nombre d'éléments contenus dans le tableau). Autrement dit, la complexité
vaut "grosso-modo" n.

Prenons un autre exemple : un algorithme qui parcourt lui aussi un tableau à n éléments. Pour
chaque case, il effectue deux tests : le nombre est-il positif ? Le nombre est-il pair ? Combien va-t-il
effectuer de tests ? La réponse est simple : deux fois plus que le premier algorithme, c'est à dire 2×n.
Autrement dit, il est deux fois plus lent. Mais pour le mathématicien ou l'informaticien, ce facteur 2 n'a
pas une importance aussi grande que cela, l'algorithme a toujours une complexité proportionnelle au
premier, et donc en O(n).

En fait, tout facteur constant peut être considéré comme négligeable. Reprenons encore notre
algorithme : il parcourt toujours un tableau à n éléments, mais à chaque case du tableau, il
reparcourt tout le tableau depuis le début pour savoir s'il n'y aurait pas une autre case ayant la même
valeur. il devra faire en tout n×n=n2 tests. Le facteur cette fois n’est pas constant ! On dira que cet
algorithme a une complexité en O(n2) ,pourtant ,c'est la complexité de certains de nos algorithmes
de tris ! Donc il est préférable d'avoir une complexité en O(n) qu'en O(n2).
def maximum(L):
m=L[0]
Exemple1 Python. Déterminer le maxi-
for i in range(1,len(L)):
mum des éléments d’une liste L non vide de
if L[i]>m:
taille n. Complexité :
m=L[i]
Tmaximum (n)  O(n)
return m

def nocc(x,L):
n=0
for y in L:
Exemple2 Python. Le nombre d’apparitions d’un élé- if x==y:
ment x dans une liste L de taille n. Complexité : n=n+1

Tnocc (n)  O(n)


return n

def majoritaire(L):
Exemple3 Python. Recherche d’un xmaj=L[0]
élément majoritaire dans une liste L de nmaj=nocc(xmaj,L)
taille n. Complexité : for i in range(1,len(L)):
if nocc(L[i],L)>nmaj:
Tmajoritaire (n)  O(n 2 ) xmaj=L[i]
nmaj=nocc(L[i],L)
return xmaj
On distingue parfois la complexité dans le meilleur cas et dans le pire cas. Il existe égale-
ment une notion de complexité en moyenne.

Exemple 4 Python. Rechercher si un élément def present(x,L):


x est présent dans une liste L de taille n. for y in L:
Complexité : if x==y:
return True
Tpresent (n)  O(n) (pire cas) return False
 O(1) (meilleur cas)

Exemple 5 Python. Construire la liste [u 0 , . . . , u n ] contenant les n  1 premiers termes


de la
suite (u n ) définie par u 0  1 et u n1  1  2u n . On donne deux versions.

def u(n): def liste_u(n):


u=1 u=1
for i in range(n): L=[u]
u=1-2*u for i in
return u range(n):
def liste_u(n): L=[] u=1-2*u
for i in range(n+1): L.append(u)
L.append(u(i)) return L
return L def u(n):
L=liste_u(
n) return
L[-1]

Ici : Tu (n)  O(n) et Tliste_u (n)  O(n 2 ). Ici : Tliste_u (n)  O(n) et Tu (n) 
O(n).
.
Exercices :

Ex. 1. Indiquez la complexité de chaque étape de l’algorithme suivant ainsi


que la complexité de la
fonction entière.
def sequence(x):
x=x+1
x=x+4
x=x*4
x = x ** 10
x = x // 2
return x

Ex. 2. Indiquez la complexité de chaque étape de l’algorithme suivant ainsi


que la complexité de la
fonction entière.
def boucle(x):
x=x+1
i=0
while i < x:
i=i+1
x=x*x
return x

Ex. 3. Indiquez la complexité de chaque étape de l’algorithme suivant ainsi


que la complexité de la
fonction entière.
def nesting(n):
m=n
sum = 0
i=0
while i < n:
j=0
while j < n:
k=0
while k < m:
sum += 2
k += 1
j += 1
i += 1
return sum
Ex. 4 Indiquez la complexité de chaque étape de l’algorithme de recherche
suivant ainsi que la complexité
de la fonction entière.
def recherche(s,x):
""" Desc : Donne l'indice ou se trouve la valeur de x dans s
INPUT : s (list), x(int)
OUTPUT : (int) indice de position de l'element (-1 si l'element n'existe pas)
"""
i=0
while i < len(s) and s[i] != x:
i = i+1
if i == len(s):
i = -1
return i
SOLUTIONS :

Solution de l’exercice 1:
Indiquez la complexité de chaque étape de l’algorithme suivant ainsi que la
complexité de la fonction
entière.
def sequence(x): # O(1)
x = x + 1 # O(1)
x = x + 4 # O(1)
x = x * 4 # O(1)
x = x ** 10 # O(log(10)) = O(1)
x = x // 2 # O(1)
return x # O(1)
Solution de l’exercice 2:
Indiquez la complexité de chaque étape de l’algorithme suivant ainsi que la
complexité de la fonction
entière.
def boucle(x): # O(x)
x = x + 1 # O(1)
i = 0 # O(1)
while i < x: # O(x)
i = i + 1 # O(1)
x = x * x # O(1)
return x # O(1)
Solution de l’exercice 3:
Indiquez la complexité de chaque étape de l’algorithme suivant ainsi que la
complexité de la fonction
entière.
def nesting(n): # O(n^2.m) = O(n^3)
m = n # O(1)
sum = 0 # O(1)
i = 0 # O(1)
while i < n: # O(n)
j = 0 # O(1)
while j < n: # O(n)
k = 0 # O(1)
while k < m: # O(m) = O(n)
sum += 2 # O(1)
k += 1 # O(1)
j += 1 # O(1)
i += 1 # O(1)
return sum # O(1)

Solution de l’exercice 4:
def recherche(s,x): # O(n)
i = 0 # O(1)
while i < len(s) and s[i] != x: # O(n)
i = i+1 # O(1)
if i == len(s): # O(1)
i = -1 # O(1)
return i # O(1)