QCM
Complexité algorithmique — vrai ou faux

1.Écrire signifie que l’algorithme effectue exactement opérations élémentaires.

2.Si la complexité dans le meilleur des cas d’un algorithme est , sa complexité dans le pire des cas est nécessairement, elle aussi, en .

3.Deux boucles imbriquées, chacune parcourant les éléments d’un tableau, donnent en général lieu à une complexité en .

4.La base du logarithme utilisée dans n’a pas d’incidence sur la classe de complexité.

5.La complexité spatiale d’un algorithme est toujours égale à sa complexité temporelle.

Exercice
Décompte d’un parcours avec condition

On considère la fonction suivante, qui compte le nombre d’éléments pairs d’une liste de entiers :

def compte_pairs(t):
    c = 0
    for x in t:
        if x % 2 == 0:
            c = c + 1
    return c

a.

En reprenant la convention de l’exemple du cours (une opération élémentaire par affectation, comparaison ou test), donner le nombre exact d’opérations effectuées par compte_pairs dans le pire des cas (préciser quelle entrée réalise ce pire cas).

Le pire cas est atteint lorsque tous les éléments de t sont pairs : à chaque itération, le test x % 2 == 0 (une opération) est vrai, donc l’affectation c = c + 1 s’exécute également (une addition et une affectation, soit deux opérations). Chaque itération coûte donc opérations dans ce cas.

En comptant l’initialisation c = 0 (une opération), les itérations (chacune à opérations dans le pire cas), et le renvoi de c (une opération), le nombre total d’opérations est :

b.

En déduire la classe de complexité de compte_pairs dans le pire des cas.

(une constante et un terme linéaire sont chacun des , donc leur somme aussi, d’après la règle de somme du cours) : compte_pairs est de complexité linéaire.

Exercice
Boucles imbriquées à bornes fixes

On considère la fonction suivante :

def produit_scalaire_toutes_paires(t):
    n = len(t)
    s = 0
    for i in range(n):
        for j in range(n):
            s = s + t[i] * t[j]
    return s

a.

Combien de fois le corps de la boucle interne (s = s + t[i] * t[j]) est-il exécuté, en fonction de  ?

La boucle externe s’exécute fois (une fois par valeur de i de à ), et pour chacune de ces valeurs, la boucle interne s’exécute également fois (une fois par valeur de j) — le nombre de répétitions de la boucle interne ne dépend pas de i. Le corps de la boucle interne est donc exécuté fois au total, conformément à la règle du cours : « pour des boucles imbriquées, multiplier les coûts ».

b.

Donner le nombre exact d’opérations élémentaires effectuées par produit_scalaire_toutes_paires, en détaillant le compte à chaque exécution du corps de la boucle interne.

Chaque exécution du corps s = s + t[i] * t[j] comporte : un accès t[i] (une opération), un accès t[j] (une opération), une multiplication (une opération), une addition (une opération), une affectation à s (une opération) — soit opérations par exécution. Comme le corps s’exécute fois (question a.), et en ajoutant l’initialisation (n = len(t) et s = 0, soit opérations) et le renvoi de s (une opération), le nombre total d’opérations est :

c.

En déduire la complexité de cette fonction.

(d’après la règle d’absorption des termes dominés, ou directement : dès que ) : produit_scalaire_toutes_paires est de complexité quadratique.

Les corrigés sont sur Intégrer

6 blocs de plus : les autres énoncés et tous les corrigés, rédigés en entier. Le reste du programme est écrit de la même main, avec les figures interactives et votre progression.