Vous êtes sur la page 1sur 21

Chapitre 1

Complexité des algorithmes

1.1 Introduction

Le terme algorithme trouve ses origines dans le surnom du mathématicien et astronome


Abou Jaafar Mouhammad Ibnou Mousa, dit Al-Khawarezmi, (783850). Dans son Kitab
Al Jabr wa al Moukabala , Al Khawarezmi a explicité des algorithmes permettant d'ef-
fectuer les opérations de l'arithmétique usuelle, telles que la multiplication, la division,
l'extraction de la racine carrée,... et ceci en utilisant la numération de position.

L'algorithmique, qui est la science de l'étude et de la conception des algorithmes, est


la composante la plus pérenne des sciences de l'informatique. Des algorithmes classiques,
connus depuis bien longtemps, continuent à intervenir dans la résolution de problèmes très
actuels et très récents. Citons, à titre d'exemple, l'algorithme d'Euclide pour le calcul du
pgcd et ses nombreuses variantes, qui se trouve à la base de plusieurs algorithmes récents
de cryptographie.
L'une des raisons derrière cette pérennité est que l'étude
des algorithmes peut se faire de manière indépendante de
l'évolution perpétuelle des langages de programmation et
des ordinateurs. Une étude indépendante de la technolo-
gie logicielle et matérielle nécessite, toutefois, des d'outils
théoriques qui permettent de comparer l'ecacité des algo-
rithmes sans avoir à les implémenter. Pour ce faire, il est né-
cessaire de préciser le modèle de machine abstraite supposée
capable d'exécuter les algorithmes étudiés. On fera aussi re-
cours aux outils mathématiques de l'analyse asymptotique,
an d'appréhender le comportement des algorithmes, no-
tamment, quand la quantité des données à traiter devient
très grande.

Une dénition possible de la notion d'algorithme est la suivante :

Un algorithme est une séquence nie d'opérations de calcul qu'une personne ou une
machine peut exécuter, an de résoudre un problème bien déterminé.

Cette dénition sous-entend que, pour qu'un algorithme soit intéressant, il doit résoudre
un problème bien déterminé. La notion d'algorithme est donc étroitement liée à celle de

1
2 CHAPITRE 1. COMPLEXITÉ DES ALGORITHMES

problème. Cette dernière peut être dénie, à son tour, comme suit :

Un problème est une question générique qui concerne un élément parmi un ensemble
d'éléments

Est-ce que deux entiers donnés sont premiers entre eux ou pas ? Cette question est un
problème, car c'est une question générique qu'on peut se poser à propos de n'importe
quelle paire d'entiers. Ceci, nous mène à la notion connexe d'instance d'un problème, qui
peut être dénie comme suit :

Une instance d'un problème est la question générique posée pour un élément particulier
de l'ensemble.

Est-ce que 57 et 1967 sont premiers entre eux ou pas ? Il s'agit d'une instance du pro-
blème de la primalité mutuelle de deux entiers, car la question est posée pour un élément
particulier de l'ensemble de toutes les paires d'entiers.
Dans ce qui suit, nous assimilerons un problème à l'ensemble de ses instances.

En général, un même problème peut être résolu par plusieurs algorithmes diérents.
Ces derniers peuvent diérer par leurs ecacités et il est naturel d'opter pour l'algorithme
le plus ecace. L'ecacité d'un algorithme dépend de la quantité de ressources qu'il utilise
pour résoudre le problème qu'il est sensé résoudre. Ces ressources sont le temps de calcul,
en premier lieu et l'espace mémoire, en second lieu. La mesure qui nous renseigne sur
la quantité des ressources utilisées par un algorithme est couramment désignée par la
complexité de l'algorithme.
Pourquoi devra-t-on étudier la complexité des algorithmes ? Intuitivement, si on veut
résoudre ecacement un problème par ordinateur, on a qu'avoir accès à un ordinateur
très rapide avec une mémoire gigantesque. Toutefois, cette intuition n'est pas tout à fait
correcte. Tout d'abord, parce que si rapide que puisse être un ordinateur, il ne peut pas
être inniment rapide. Le temps de calcul sur ordinateur est donc une ressource limitée.
Il en est de même de l'espace mémoire, bien que cette ressource est plus disponible, en
pratique. Il est donc essentiel d'utiliser des algorithmes performants pour espérer aboutir
à une résolution rapide.

1.2 Un premier exemple

On se propose d'arranger une (longue) séquence de nombres dans l'ordre croissant. Ce


problème, qu'on appelle couramment problème de tri, est une tâche majeure en infor-
matique, (un système d'exploitation, par exemple, passe une bonne partie de son temps
à eectuer des tris), ce qui explique la multitude d'algorithmes de tri dont on dispose
1
déjà . Le choix du problème de tri n'est pas fortuit, mais motivé par le cadre oert par ce
problème an d'introduire de nombreuses techniques de conception et d'outils d'analyse
d'algorithmes, comme nous le verrons tout au long de ce cours.

Le problème de tri peut se dénir formellement comme suit :


Entrée : une séquence ha1 , a2 , . . . , an i de n nombres.
1. Il y a, entre autres, le tri bulles, le tri par insertion, le tri par fusion, le tri rapide, le tri par tas...
1.3. LE MODÈLE DE MACHINE ABSTRAITE 3

temps

Tri inecace sur ordinateur rapide

Tri ecace sur ordinateur lent

taille de la séquence à trier

Figure 1.1  Comparaison des performance d'un tri ecace s'exécutant sur un ordinateur
lent vs un tri inecace s'exécutant sur un ordintaur rapide.

Sortie : une permutation hπ(a1 ), π(a2 ), . . . , π(an )i de la séquence donnée en entrée telle
que π(a1 ) ≤ π(a2 ) ≤ . . . ≤ π(an ).

Dans ce qui suit, nous illustrons l'importance d'un algorithme ecace par une ex-
périmentation dont les résultats montrons qu'un algorithme ecace implémenté sur un
ordinateur lent peut s'avérer plus performant qu'un mauvais algorithme implémenté sur
un ordinateur plus rapide. L'expérimentation que nous allons exposer suppose, comme on
peut le deviner, que l'on dispose d'au moins deux algorithmes qui résolvent le même pro-
blème. Pour ce faire, intéressons nous, de nouveau, au problème de tri. Nous avons déjà
signaler qu'il existe plusieurs algorithmes de tri. Nous allons focaliser sur deux d'entre
eux. Le premier, appelé tri par insertion, n'est pas particulièrement ecace. Le second,
appelé tri par fusion, est l'un des tris les plus ecaces qui existent. La Figure 1.1, montre
les performances des deux tris cités ci-dessus en fonction de la taille des données à trier.
On constate que, quand la taille des données à trier dépasse une certaine limite, le tri par
fusion donne de meilleures performances, bien qu'il soit exécuté sur une machine qui est
deux fois moins rapide.

1.3 Le modèle de machine abstraite

Bien qu'indépendante des machines réelles, l'analyse des algorithmes suppose, tout de
même, un modèle abstrait de calcul. En eet, la complexité d'un algorithme n'est pas
la même si on l'exécute sur une machine permettant l'accès direct aux zones mémoires
que sur une machine qui ne le permet pas (une machine de Turing, par exemple). Il
est donc indispensable de préciser le modèle de machine abstraite qui sera utilisée pour
exécuter les algorithmes étudiés une fois transformés en programmes. Choisir un modèle
de calcul, c'est principalement, préciser les ressources disponibles avec ce modèle. Dans
ce cours, on suppose que la machine abstraite est une machine à mémoire à accès direct
(machine RAM) avec une seule unité de calcul. Une telle machine permet d'accéder à une
zone mémoire, dont on connais l'adresse, en une unité de temps. Toutefois, une machine
RAM exécute les instructions l'une après l'autre sans avoir la possibilité d'eectuer des
opérations en parallèle. Les machines abstraites du type RAM permettent, néanmoins,
4 CHAPITRE 1. COMPLEXITÉ DES ALGORITHMES

d'eectuer des opérations élémentaires en un nombre constant d'unité de temps. Ces


opérations élémentaires sont :
 l'accès à une zone de mémoire à partir d'une adresse,
 l'aectation (:=),
 les comparaisons (=,<>,<,>,<=,>=),
 les opération arithmétiques et logiques (+, -, *, /, div, mod, non, et, ou),
 la saisie et l'achage de données élémentaires,...
Ces opérations seront donc considérées comme les opérations élémentaires de notre ma-
chine RAM. En revanche, déterminer, par exemple, la primalité d'un nombre entier ne
peut être considéré comme une opération élémentaire, car il est irréaliste qu'on puisse
concevoir des machines RAM qui puissent réaliser cette tâche en un nombre constant
d'unité de temps.
Pour des raisons de simplicité, le modèle RAM fait des suppositions qui ne corres-
pondent pas exactement au fonctionnement réel des ordinateurs. Par exemple, le modèle
RAM suppose qu'une multiplication et une addition se déroulent, toute deux, en une unité
de temps. En réalité, sur n'importe quelle machine réelle, une multiplication prend plus
de temps qu'une addition. Toutefois, une telle entorse à la réalité peut être justiée par
la diérence entre les temps de calcul de ces deux opérations, qui n'est pas si importante
que ça. Le modèle RAM s'appuie sur un ensemble de simplications justiées du genre
de celle qui vient d'être citée en exemple. C'est grâce à ces simplications qu'on a abouti
à un modèle de machine simple tout en étant capable d'appréhender le comportement des
algorithmes, une fois implémentés sur de vrais ordinateurs.

Par ailleurs, les types de données considérés comme élémentaires dans le modèle RAM
sont les types booléen, caractère, entier et réel. Ceci suppose que, pour stocker une unité de
chacun de ces types de données élémentaires, on a besoin d'un nombre constant d'unités
mémoire. Cette hypothèse à, tout de même, une conséquence, c'est qu'il y aura une limite
à la grandeur des nombres qu'on peut représenter dans le modèle. Signalons, enn, que
pour certains problèmes, on est amené à considérer que la donnée élémentaire est le bit ;
le problème de la primalité d'un entier en est l'exemple le plus représentatif.

1.4 La complexité dans tous ses états

Comme nous l'avons mentionné dans l'introduction, l'ecacité d'un algorithme dépend
de la quantité de ressources qu'il utilise pour résoudre le problème qu'il est sensé résoudre.
Ces ressources sont le temps de calcul, en premier lieu et l'espace mémoire, en second lieu.
La mesure qui nous renseigne sur la quantité de ressources utilisées par un algorithme
est couramment désignée par la complexité de l'algorithme. Ainsi, on distingue la com-
plexité temporelle et la complexité spatiale. Dans ce qui suit, nous étudions exclusivement
la complexité temporelle, car cette dernière mesure une ressource plus limitée que celle
mesurée par la complexité spatiale. Désormais, la complexité temporelle d'un algorithme
sera désignée par complexité de l'algorithme, tout court.
Comme toute mesure, la complexité d'un algorithme doit avoir une unité. Pour que la
complexités soit exprimée de manière indépendante de la technologie, (l'ordinateur utilisé
pour exécuter l'algorithme, une fois codé dans un langage de programmation), on utilise le
nombre d'opérations élémentaires comme unité, au lieu du temps de calcul. Les opérations
1.4. LA COMPLEXITÉ DANS TOUS SES ÉTATS 5

considérées comme élémentaires sont déterminées par le choix de la machine abstraite,


dans notre cas, le modèle RAM (voir Section 1.3).

D'un autre coté, la complexité d'un algorithme va naturellement dépendre de la quan-


tité des données sur lesquelles l'algorithme va s'exécuter. En général, plus cette quantité
est grande, plus l'algorithme sera amené à eectuer des calculs. Il est donc nécessaire de
savoir mesurer la taille des données. En théorie, c'est le nombre de bits nécessaires pour
coder les données qui est utilisé comme mesure. Toutefois, pour des raisons de simplicité,
on utilise souvent le nombre de données élémentaires, (le booléen, le caractère, l'entier ou
le réel). Étant donné que le nombre de bits nécessaires pour coder un nombre p ne dé-
passe pas c log p bits, où c est une constante, compter en nombre de données élémentaires
ne pose pas de problème, car souvent, on a c log p  n, où n est le nombre de données
élémentaires.

Calculer la complexité d'un algorithme revient à établir une relation entre la taille
des données en entrée, d'une part, et le nombre d'opérations élémentaires eectuées par
l'algorithme en s'exécutant sur ces données, d'autre part. Cette relation peut être exprimée
par une fonction mathématique qui utilise, comme argument, la taille des données en
entrée et renvoie, comme image, le nombre d'opérations élémentaires que l'algorithme
serait amené à eectuer en s'exécutant sur des données de cette taille.

Dénition 1. La complexité d'un algorithme est la mesure du nombre d'opérations


élémentaires que l'algorithme peut être amené à eectuer sur un jeu de données.
Elle est représentée par une fonction, f (n), exprimant le nombre d'opérations élé-
mentaires en fonction de la taille des données n.

Soit P un problème et soit A un algorithme qui résout P. En utilisant le modèle


de machines abstraites RAM, on peut compter combien d'opérations élémentaires sont
nécessaires pour que A résout une instance I de P. Cependant, ce nombre peut varier
d'une instance à une autre. Cette variabilité donne lieu à trois mesures diérentes de la
complexité :

 La complexité dans le cas le moins favorable correspond au plus grand nombre


d'opérations élémentaires que A serait amené à exécuter sur une des instances de
P. Cette complexité est relativement facile à évaluer et, au même temps, donne
une information très utile sur le comportement de algorithme. C'est la complexité
la plus étudiée et utilisée.
 La complexité dans le cas le plus favorable, qui correspond au nombre d'opéra-
tions élémentaires qu'il faut exécuter pour résoudre l'instance la moins coûteuse
du problème P.
 La complexité moyenne est calculée en prenant l'espérance mathématique des
nombres d'opérations élémentaires eectuées pour résoudre chacune des instances
du problème. L'avantage de cette complexité c'est qu'elle reète le comportement
général de l'algorithme et non pas les cas extrêmes, (les deux cas précédents), qui
sont rares. La complexité moyenne est particulièrement signicative dans le cas où
la complexité varie peu en fonction des données.
Plus formellement, soit X une variable aléatoire discrète qui prend ses valeurs dans
6 CHAPITRE 1. COMPLEXITÉ DES ALGORITHMES

l'ensemble suivant :

ω(n) = {x ∈ N : ∃I ∈ P, |I| = n et A eectue x opérations élémentaires sur I}

où |I| désigne la taille de l'instance I. La complexité moyenne de l'algorithme A


sur des données de taille n est alors donnée par

µ(n) = E[X]

où E désigne l'espérance mathématique. Si on dispose de la loi de probabilité de


la variable aléatoire X alors on peut écrire :

X
µ(n) = xp(x) (1.1)
x∈ω(n)

où p(x) est la probabilité qu'une instance de P se résout en eectuant x opéra-


tions élémentaires. Toutefois, la loi de probabilité que suit la variable X est parfois
dicile à avoir, (et même à estimer), en pratique. Ce qui fait que la complexité
moyenne est, de loin, la complexité la plus dicile à établir.

Bien que diérentes, ces trois complexités seront exprimées par des fonctions dont l'unique
argument est la taille des données, comme indiqué dans la Dénition 1.

Exemple 1. Considérons l'algorithme d'Euclide, qui permet de calculer le plus grand


diviseur commun (pgcd) de deux nombres entiers naturels (voir Algorithme 1). En partant
du fait que le reste d'une division entière est toujours strictement inférieur au diviseur,
on conclut que la boucle Tant-que va se dérouler, au plus, b fois. À l'intérieur de cette
boucle, il y a 5 opérations élémentaires : 3 aectations, un test et un calcul de modulo.
Avant et après la boucle, il y a 5 autres opérations élémentaires (toutes des opérations
d'entrée sortie). Pour résumer, on peut dire que la complexité de l'algorithme d'Euclide,
dans le cas le moins favorable, est majoré par 5b + 5. Le nombre b est, à son tour, majoré
n
par 2 − 1, où n désigne le nombre de bits servant à coder les données du problème, à
savoir a et b. D'où, une borne supérieure qui est une fonction exponentielle en la taille
des données : 5 × 2n
Néanmoins, il y a mieux comme majorant. En eet, le mathématicien Gabriel Lamé
(17951870) a montré le théorème suivant :

Theorem 1. Le nombre de divisions à eectuer pour trouver le pgcd de deux entiers


naturels à l'aide de l'algorithme d'Euclide ne dépasse pas cinq fois le nombre de
chires dans l'écriture décimale du plus petit des deux nombres.

Donc, d'après ce théorème, le nombre de passage dans la boucle est borné par 5 log10 b
= 1.51 log2 b. Rappelons que n est le nombre de bits nécessaires pour coder, en binaire,
les nombres a et b, c'est-à-dire, que n est la taille, en bits, des données. On a alors
n ≥ log2 a+log2 b. On peut alors majorer le nombre de passage dans la boucle par 1.51n. Il
s'ensuit que le nombre total d'opérations élémentaires eectuées pas l'algorithme d'Euclide
est majoré par 7.55n + 5.
Cependant, on peut facilement constater que, si b divise a, l'algorithme d'Euclide n'exé-
cutera qu'une seule itération, il s'agit là du cas le plus favorable. Entre le cas le moins
1.4. LA COMPLEXITÉ DANS TOUS SES ÉTATS 7

Algorithme Euclide
Variables
a, b, r : entiers
début
Ecrire("Donnez un entier a")
Lire(a)
Ecrire("Donnez un entier b tel que 0 < b ≤ a")
Lire(b)
tant que b > 0 faire
r := a mod b
a := b
b := r
n
Ecrire("Le pgcd est : ",a)
n
Algorithme 1 : Algorithme d'Euclide pour le calcul du pgcd de deux entiers.

favorable et le cas le plus favorable, il peut y avoir un grand nombre de cas intermédiaires.
On serais alors tenter d'évaluer le nombre moyen d'opérations élémentaires eectuées
par l'algorithme d'Euclide sur l'ensemble de toutes les instances du problème du pgcd. Ce
2
nombre est évalué à (12 ln 2 ln n)/π + 1.47 et sont calcul est fastidieux.

Exemple 2. An d'illustrer la notion de complexité moyenne, considérons un simple


problème de recherche d'un élément donné dans un ensemble de n entiers appartenant
au sous-ensemble d'entiers {1, 2, . . . , k}. Une fonction qui résout ce problème est détaillée
dans l'algorithme 2. Dans cette dernière, on suppose que les éléments de l'ensemble sont
stockés dans un tableau pas forcement trié.
n+1 2
Une analyse ne du problème révèle qu'il admet, en tout, k instances diérentes ,
n
parmi lesquelles k(k − 1) instances impliquent un tableau qui ne contient pas l'élément
recherché. La probabilité d'avoir une de ces instances négatives est donc donnée par :

(k − 1)n
kn

Notez que, sur ces instances, la fonction de recherche ira jusqu'au bout et eectuera donc
n itérations.
Toutes les autres instances contiennent l'élément recherché et donc la première occur-
rence de cet élément occupera une case i du tableau, avec 1 ≤ i ≤ n. Le nombre d'instances
dans lesquelles la première occurrence de l'élément recherché occupe la position i est donné
i−1
par (k − 1) kk n−i . Ce qui fait que la probabilité d'avoir une de ces instances est donnée
par :
(k − 1)i−1
ki
2. Il faut tenir compte de l'élément recherché, qui est aussi une donnée, en plus des n entiers.
8 CHAPITRE 1. COMPLEXITÉ DES ALGORITHMES

Fonction ChercheElt(tab : tableau d'entier, n : entier, elt : entier) : booléen


Variables
i : entier
début
pour i:= 1 à n faire
si tab[i] = elt alors retourner vrai
n
retourner faux
n
Algorithme 2 : Recherche d'un élément dans un tableau non trié.

On déduit, d'après (1.1), que la complexité moyenne de notre fonction est :

n
(k − 1)n X (k − 1)i−1
µ(n) = n + i
kn i=1
ki
3
En utilisant l'identité suivante
n
X 1 + xn (nx − n − 1)
ixi−1 =
i=1
(1 − x)2

On obtient, (après beaucoup de calculs)

(k − 1)n (k − 1)n n  1 
µ(n) = n + 1− (1 + ) k = 1 − (1 − )n k
kn k n k k

1.5 Notations asymptotiques

Bien qu'il soit parfois possible de déterminer la complexité d'un algorithme en précisant
le nombre exact d'opérations élémentaires eectuées, cette précision n'est, en général, pas
nécessaire. En eet, pour des entrées susamment grandes, les eets des constantes multi-
plicatives et des termes d'ordre inférieur intervenant dans la fonction qui exprime la com-
plexité sont négligeables par rapport aux eets de la taille de l'entrée. Dans l'Exemple 1,
on a trouvé que f (n) ≤ 7.55n + 5, toutefois, quand n est assez grand, on peut négliger la
constante multiplicative, 7.55, et le terme d'ordre inférieur, 5, et ne garder que le terme n.
On ne s'intéresse alors plus à la complexité exacte d'un algorithme mais plutôt à l'ordre
de grandeur asymptotique de celle-ci.
L'ordre de grandeur asymptotique de la complexité d'un algorithme donne une carac-
térisation simple de l'ecacité d'un algorithme et permet de comparer les performances
d'algorithmes résolvant le même problème. Quand on prend des entrées susamment
grandes pour que seul compte réellement l'ordre de grandeur de la complexité, on étu-
die les performances asymptotiques des algorithmes. Plus précisément, on étudie la façon
avec laquelle augmente le nombre d'opérations élémentaires eectuées par un algorithme
quand la taille des données augmente indéniment.

Pn
3. Peut être obtenue en dérivant les deux termes de l'identité
i=1 xi = (1 − xn+1 )/(1 − x).
1.5. NOTATIONS ASYMPTOTIQUES 9

Les fonctions mathématiques étudiées dans ce chapitre permettront de mesurer la


complexité des algorithmes. Or, la complexité d'un algorithme exprime le nombre d'opé-
rations élémentaires eectuées par cet algorithme. Il s'agit donc de fonctions à valeurs
dans R+ . Ce sont donc des fonctions positives. De plus, l'unique argument de chacune de
ces fonctions est sensé représenter une quantité de données. Or, la quantité de données en
entrée d'une instance d'un problème est exprimée par un entier naturel. On pourra donc
se limiter, dans notre étude de l'ordre de grandeur de la complexité des algorithmes, à
des fonctions de N → R+ .

1.5.1 La notation O
La notion d'ordre de grandeur asymptotique peut nous donner une borne asymptotique
supérieure de la fonction qu'on veut borner asymptotiquement. C'est ce que permet de
faire les classes paramétrées de fonctions notées O(.), qui sont dénies comme suit :

Dénition 2. Soient f (n) et g(n) deux fonctions positives. On dit que f (n) est
dans O(g(n)) s'il existe des constantes c > 0 et n0 ≥ 0 telles que, pour tout n ≥ n0 ,
on a f (n) ≤ c.g(n).

Quand f (n) ∈ O(g(n)), on dit que f (n) est de l'ordre de g(n). Ainsi, si la complexité
d'un algorithme A est exprimée par une fonction de O(g(n)), pour une fonction g(n)
donnée, alors g(n) exprime l'ordre de grandeur asymptotique de la complexité de A dans
le cas le moins favorable (le pire des cas), car dans la Dénition 2, f (n) doit être bornée
supérieurement par c.g(n), quelque soit n ≥ n0 .

Exemple 3.
 La fonction f (n) = 12 n2 + 21 n est dans O(n2 ), car pour tout n ≥ 1, 1 2 1
on a 2 n + 2 n ≤
2n2 .
2
 La fonction f (n) = 3n x+1
+2n−1
est dans O(n), car pour tout n ≥ 0, on a f (n) ≤ 3n.
 log(n) est dans O(n), car log(n) ≤ n, pour tout n.
√ √
 n est dans O(n), car n ≤ n, pour tout n ≥ 1.
 2n est dans O(n!), car on a 2n ≤ n!, pour tout n ≥ 4.

L'appartenance aux classes de la notation O satisfait une forme de pseudo-transitivité,


qui est dénie comme suit :

Lemme 2. Soient f (n), g(n) et h(n) trois fonctions positives. Si f (n) ∈ O(g(n))
et g(n) ∈ O(h(n)) alors f (n) ∈ O(h(n))

Preuve. Soit f (n) ∈ O(g(n)) g(n) ∈ O(h(n)), ce qui implique que :


et
 il existe des constantes c > 0 et n0 ≥ 0 telles que f (n) ≤ cg(n), pour tout n ≥ n0 .
0 0 0 0
 il existe des constantes c > 0 et n0 ≥ 0 telles que g(n) ≤ c h(n), pour tout n ≥ n0 .
0 0
Il en résulte que f (n) ≤ cc h(n), pour tout n ≥ max(n0 , n0 ). De ceci, on déduit que
f (n) ∈ O(h(n)).

Le lemme suivant énoncent deux propriétés des classes de la notation O qui impliquent
la somme de fonctions :
10 CHAPITRE 1. COMPLEXITÉ DES ALGORITHMES

Algorithme DeuxBlocs
début
un premier bloc de complexité dans O(f (n))

un second bloc de complexité dans O(g(n))


n
Algorithme 3 : Schéma d'un algorithme constitué de deux blocs séquentiels de
traitement.

Lemme 3. f (n) et g(n) deux fonctions positives.


Soient
(i) f (n) ∈ O(g(n)) ⇒ f (n) + g(n) ∈ O(g(n)).
(ii) O(f (n) + g(n)) = O(max(f (n), g(n))).

Preuve.
(i) De l'appartenance de f (n) à O(g(n)), on déduit qu'il existe des constantes c et n0
telles que f (n) ≤ cg(n), pour tout n ≥ n0 . Il en résulte que f (n)+g(n) ≤ (c+1)g(n),
pour tout n ≥ n0 . De ceci, on déduit que f (n) + g(n) ∈ O(g(n)).

(ii) Montrons que O(f (n)+g(n)) ⊆ O(max(f (n), g(n))). Soit h(n) ∈ O(f (n)+g(n)),
ce qui implique qu'il existe deux constantes c et n0 telles que h(n) ≤ c(f (n)+g(n)),
pour tout n ≥ n0 . Ceci implique que h(n) ≤ 2c max(f (n), g(n)), pour tout n ≥ n0 ,
et donc h(n) ∈ O(max(f (n), g(n))).
Montrons, à présent que, O(f (n) + g(n)) ⊇ O(max(f (n), g(n))).
Soit h ∈ O(max(f (n), g(n))), ce qui implique qu'il existe deux constantes c et
n0 telles que h(n) ≤ c max(f (n), g(n)), pour tout n ≥ n0 . Ceci implique que
h(n) ≤ c(f (n) + g(n)), pour tout n ≥ n0 , car f et g sont des fonctions dans R+ . Il
s'ensuit que h(n) ∈ O(f (n) + g(n)).

Le Lemme 3 peut être appliquer pour calculer la complexité d'un algorithme constitué
de deux blocs de traitements séquentiels de complexité asymptotique respective dans
O(f (n)) et O(g(n)) (voir Algorithme 3).

Lemme 4. Soientf (n) et g(n) deux fonctions positives. Alors on a


O(f (n))O(g(n)) = O(f (n)g(n)), où

O(f (n))O(g(n)) =def {h : ∃h1 (n) ∈ O(f (n)), ∃h2 (n) ∈ O(g(n)), h(n) = h1 (n)h2 (n)}

Preuve. Montrons, d'abord, que O(f (n))O(g(n)) ⊆ O(f (n)g(n)).


Soit h(n) ∈ O(f (n))O(g(n)), donc il doit exister h1 (n) ∈ O(f (n)), h2 (n) ∈ O(g(n))
telles que h(n) = h1 (n)h2 (n). Par dénition de O(f (n)) et O(g(n)), on doit avoir
 (∃c1 > 0)(∃n1 ≥ 0)(∀n ≥ n1 ), h1 (n) ≤ c1 f (n)
 (∃c2 > 0)(∃n2 ≥ 0)(∀n ≥ n2 ), h2 (n) ≤ c2 g(n)
1.5. NOTATIONS ASYMPTOTIQUES 11

Algorithme ProduitDeComplexité
début
.
.
.
pour i :=1 à n faire
Ecrire(RecheDicho(mat[i],i,n))
n
.
.
.
n
Algorithme 4 : Un bout d'algorithme dont la complexité s'exprime par le produit
de deux complexités.

Il s'ensuit que, pour tout n ≥ max(n1 , n2 ), on a h(n) = h1 (n)h2 (n) ≤ c1 c2 f (n)g(n), ce


qui implique que h(n) ∈ O(f (n)g(n)).

Montrons, à présent, que O(f (n))O(g(n)) ⊇ O(f (n)g(n)).


Soit h(n) ∈ O(f (n)g(n)). Il existe alors c > 0 et n0 ≥ 0 telles que h(n) ≤ cf (n)g(n),
pour tout n ≥ n0 . Dénissons deux fonctions h1 et h2 telles que h1 = f , (et donc h1 (n) ∈
O(f (n))), et h2 est dénie comme suit

h(n)/f (n) si f (n) 6= 0
h2 (n) = (1.2)
0 sinon

On a h(n) = h1 (n)h2 (n), ce qui implique que h1 (n)h2 (n) ≤ cf (n)g(n) et par conséquent
f (n)h2 (n) ≤ cf (n)g(n). D'après (1.2), on déduit que h2 (n) ≤ cg(n). Ceci montre que
h2 (n) ∈ O(g(n)). D'où h(n) ∈ O(f (n))O(g(n)).

Exemple 4. On voudrait savoir si les lignes triés d'une matrice d'entiers ( mat) contiennent
des entiers qui sont plus petits ou égaux à l'indice de la ligne. On pourrait alors utiliser le
bout d'Algorithme 4, qui est composé de deux boucles imbriquées qui permettent de répéter
une recherche dichotomique n O(n). La
fois, donc un nombre de répétition de l'ordre de
complexité, dans le pire des cas, d'une recherche dichotomique est de l'ordre de O(log n).
En appliquant le Lemme 4, on déduit que la complexité de l'Algorithme 4 est O(n log n).

Le nombre d'opérations élémentaires eectuées par un grand nombre d'algorithmes


usuels est exprimé par un polynôme ayant la taille des donnée comme variable, d'où
l'intérêt du théorème suivant.

Theorem 5. Soit f (n) = ak nk + ak−1 nk−1 + . . . + a1 n + a0 , où ak , ak−1 , . . . , a1 , a0


k
sont des constantes réelles. Alors f (n) est dans O(n ).

Pk  k
Preuve. Pour tout n ≥ 1, on a f (n) ≤ i=0 |ak | n . On peut alors prendre c =
max(1, ki=0 |ak |), qui est une constante non nulle, et n0 = 1.
P

Le Théorème 5, est particulièrement utile quand le corps de l'algorithme se compose


principalement d'une imbrication de boucles (voir Algorithme 5). Ainsi, si le corps de
l'algorithme se compose de k boucles imbriquées, exécutant chacune n itérations alors, en
12 CHAPITRE 1. COMPLEXITÉ DES ALGORITHMES

.
.

. a0 opérations
pour i1 := 1 à n faire
.
.

. a1 opérations
pour i2 := 1 à n faire
.
.

. a2 opérations
..
.
.
.

. ak−1 opérations
pour ik := 1 à n faire
.
.

| . ak opérations
n
n
n
Algorithme 5 : Imbrication de k boucles pour

appliquant le Théorème 5, on déduit que la complexité de l'algorithme est O(nk ).

Theorem 6. Si c est une constance positive alors f (n) = 1 + c + c2 + . . . + cn est


dans :
 O(1) si c < 1.
 O(n) si c = 1.
 O(cn ) si c > 1.

Preuve. A établir sous-forme d'exercice.

Exercice 1. Montrez que :


 (x + y)2 ∈ O(x2 + y 2 )
 2n ∈ O(2n+1 )
 log n! ∈ O(n log n)
 (log n)k ∈ O(n), pour toute constante k ≥ 1
 nk ∈ O(k n ), pour toute constante k > 1
ε
 pour toute constante ε > 0, on a log n ∈ O(n ).

Ci-desous une liste d'appellations faisant partie du vocabulaire employé pour décrire
la complexité d'une grande part des algorithmes les plus usités.
On dit qu'un algorithme se déroule en temps :

 constant si sa complexité, dans le pire des cas, est bornée par une constante, dans
O(1) donc.
 logarithmique si sa complexité, dans le pire des cas, est dans O(log n)
 linéaire si sa complexité, dans le pire des cas, est dans O(n).
 super-linéaire si sa complexité, dans le pire des cas, est dans O(n log n).
 quadratique si sa complexité, dans le pire des cas, est dans O(n2 ).
1.5. NOTATIONS ASYMPTOTIQUES 13

 cubique si sa complexité, dans le pire des cas, est dans O(n3 ).


c
 polynomial si sa complexité, dans le pire des cas, est dans O(n ), pour une constante
c.
p
 exponentiel si sa complexité, dans le pire des cas, est dans O(2n ), où p>0 est
une constante.
 factoriel si sa complexité, dans le pire des cas, est dans O(n!).

En général, un algorithme dont la complexité a le plus petit ordre de grandeur asymp-


totique dans le cas le moins favorable, constitue le meilleur choix. Ainsi, en comparant, les
fonctions asymptotiques dans le cas le moins favorable associées à diérents algorithmes
qui résolvent le même problème, on peut déterminer celui qui est le plus ecace.

Dénition 3. Un algorithme A qui résout un problème P est dit optimal si sa


complexité f (n) et la complexitég(n) de tout autre algorithme résolvant P vérient
f (n) ∈ O(g(n)).

Dans l'absolu, on convient qu'un algorithme est dit ecace s'il est polynomial, c'est-
à-dire, si sa complexité, dans le pire des cas, est polynomiale.

Comment peut-on déterminer l'ordre de grandeur auquel appartient la complexité,


dans le pire des cas, d'un algorithme donné ? Une technique de calcul qui marche dans
bien des cas consiste à étudier la variation du nombre d'opérations élémentaires f (n)
quand la taille des données, n, augmente (notamment, d'une unité). On essayera donc de
trouver une relation entre f (n + 1) et f (m), pour n ≥ m. Ainsi, si on a :

 Si f (n + 1) = f (n) alors f (n) ∈ O(1).


 Si f (n + 1) = f (n) + O(1) alors f (n) ∈ O(n).
 Si f (n + 1) = f (n) + O(n) alors f (n) ∈ O(n2 )
 Si f (n + 1) = f (d n2 e) + O(1) alors f (n) ∈ O(log n)
 Si f (n + 1) = 2f (n) alors f (n) ∈ O(2n )
 Si f (n + 1) = nf (n) alors f (n) ∈ O(n!)
D'autres techniques plus élaborées de calcul de la complexité dans le pire des cas seront
étudiées dans les prochains chapitres.

Exercice 2. Décrire la démarche d'un algorithme simple pour chacun des problèmes
suivants, puis déterminez sa complexité :
 La détermination d'une entrée précise d'un tableau à deux dimensions.
 La recherche d'un élément dans un tableau trié.
 La détermination de la valeur maximale d'un ensemble d'entiers stocké dans
un tableau.
 La détermination de l'élément le plus fréquent dans un ensemble d'entiers
stocké dans un tableau.
 La multiplication de deux matrices carrées de taille n × n.
 La satisabilité d'une formule logique donnée sous forme normale conjonc-
tive.
 Le problème du voyageur de commerce.
14 CHAPITRE 1. COMPLEXITÉ DES ALGORITHMES

1.5.2 La notation Ω
De même que la notation O fournit une borne asymptotique supérieure pour une fonction
donnée, la notation Ω fournit aussi une borne asymptotique, mais inférieure, cette fois.
Pour une fonction g(n) donnée, on note Ω(g(n)) l'ensemble des fonctions qui vérient la
dénition suivante :

Dénition 4. Une fonction f (n) est dans Ω(g(n)) s'il existe des constantes c>0
et n0 ≥ 0 telles que, pour tout n ≥ n0 , on a c.g(n) ≤ f (n).

La notation Ω permet donc de borner inférieurement une fonction f (n) par c.g(n), pour
tout n ≥ n0 . Puisque cette borne inférieure est valable quelque soit l'instance du problème
sur laquelle on exécute l'algorithme en question, O(g(x)) correspond à l'ordre de grandeur
asymptotique de la complexité de l'algorithme dans le cas le plus favorable.

Exemple

5.
 n ∈ Ω(log√n). Il sut de prendre c = 1 et n0 = 1.
 log n ∈
/ Ω( n). Pour montrez
√ ceci, procédant par l'absurde. Supposons qu'il existe
c > 0 et n0 ≥ 0 tels que c n ≤ log
√n, pour tout n ≥ n0 . Soit
√ m = max(2, 1/c, n0 ).
16 16 1
16
Puisque m ≥ n0 , on doit avoir c m ≤ log m , et donc m ≤ c log m16 . Ceci
16
8 41
implique qu'on doit avoir m ≤ 2 c log m. En majorant 2, 1/c et log m par m, on
8 6
obtient m ≤ m , ce qui est impossible car m ≥ 2.

Exemple 6. Le tri par insertion consiste à parcourir le tableau à trier T et, pour chaque
case i, on procède à l'insertion de l'élément T[i] dans le sous-tableau T[1..i-1], qui est
supposé déjà trié. Pour que l'élément T[i] puisse être inséré à la position qui lui est due,
on procède au décalage, vers la droite, des éléments qui lui sont supérieurs dans le sous-
tableau T[1..i-1]. La démarche du tri par insertion est détaillée dans l'algorithme 6.
Intéressons nous, à présent, à la complexité du tri par insertion dans le cas le plus
favorable. Il est facile de constater que la boucle externe est répétée n−1 fois quelque soit
le tableau à trier. Cette boucle contient 4 aectations plus le test de la condition de la
boucle interne. Ceci implique que 5(n − 1) ≤ f (n), où f (n) désigne la complexité du tri
par insertion. De ceci, on déduit que f (n) ∈ Ω(n). Cependant, si le tableau qu'on voudrait
trier est déjà trié, alors la boucle interne ne sera pas exécutée. Ceci veut dire, qu'il existe
une instance du problème pour laquelle on a f (n) = 5(n − 1). La classe Ω(n) est donc la
classe polynomiale la plus appropriée pour la complexité du tri par insertion dans le cas
le plus favorable.

Exercice 3. Montrez que si f (n) ∈ Ω(g(n)) alors g(n) ∈ O(f (n)).

1.5.3 La notation Θ
La classe de complexité asymptotique O étudiée ci-dessus fournit une borne asymptotique
supérieur d'une fonction positive f (n) données. Il est possible de dériver une borne plus
précise que celle fournie par la notation O . Pour ce faire, on dénit, pour toute fonction
à une variable g(n), l'ensemble des fonctions noté Θ(g(n)) comme suit :
1.5. NOTATIONS ASYMPTOTIQUES 15

Procédure TriInsertion(T : tableau d'entier, n : entier)


Variables
i, j, v : entier
début
pour i :=2 à n faire
v := T[i]
j := i
tant que j > 1 et T[j-1] > v faire
T[j] := T[j-1]
j := j-1
n
T[j] := v
n
n
Algorithme 6 : Procédure réalissant le tri par insertion.

Dénition 5. Une fonction f (n) est dans l'ensemble Θ(g(n)), s'il existe des
constantes c1 , c2 > 0 et n0 ≥ 0 telles que, pour tout n ≥ n0 , on a c1 .g(n) ≤
f (n) ≤ c2 .g(n).

En des termes plus simples, la fonction f (n) appartient à Θ(g(n)) si f (n) peut être
encadrée par c1 g(n) et c2 g(n) quand n est assez grand. La Figure 1.2 illustre les positions
relatives des fonctions f (n) et g(n) qui vérient la Dénition 5. On constate que, pour
toutes les valeurs de n situées à droite de n0 , la valeur de f (n) est supérieure ou égale
à c1 g(n) et inférieure ou égale à c2 g(n). Autrement dit, pour tout n ≥ n0 , la fonction
f (n) est égale à g(n) à un facteur constant près. On dit alors que g(n) est une borne
asymptotiquement approchée de f (n).

Exemple 7.
1 2 1 2
 Montrons que 2 n + 2 n ∈ Θ(n ). Pour ce faire, on doit déterminer des constantes
2 1 2 1 2
positives c1 , c2 > 0 et n0 telles que c1 n ≤ 2 n + 2 n ≤ c2 n , pour tout n ≥ n0 . Il
1
sut donc de prendre c1 = 2 , c2 = 1 et n0 = 1.

 Montrons, à présent, que n ∈/ Θ(n). On montre précisément qu'il n'existe pas

c1 > 0 et n0 ≥ 0 tels que c1 n ≤ n, pour tout n ≥ n0 . Pour ce faire, on suppose
qu'il existe de telles constantes. Remarquer qu'on doit avoir c1 < 1. Il s'ensuit
q que,

pour tout n≥ n0 , on a ( n+1


c1
)2 n+1 2 n+1 2
≥ n ≥ n0 . On doit donc avoir c1 ( c1 ) ≤ ( c1 ) =
n+1
c1
, pour tout n ≥ n0 . Il en résulte que (n + 1)2 ≤ n + 1, pour tout n ≥ n0 , ce qui
ne peut pas être vrai.

Le théorème suivant établi un lien entre les trois notations asymptotiques étudiées :

Theorem 7. f (n) ∈ Θ(g(n)) si et seulement si f (n) ∈ (Ω(g(n)) ∩ O(g(n))).

Preuve. On procède en montrant chacune des deux implications à part.


16 CHAPITRE 1. COMPLEXITÉ DES ALGORITHMES

Figure 1.2  La notation O donne la borne asymptotique supérieure, exprimée par


c2 .g(n). La notation Ω donne la borne asymptotique inférieure, exprimée par c1 .g(n).
La notation Θ procure les deux bornes à la fois.

Soitf (n) ∈ Θ(g(n)), ce qui implique qu'il existe c1 , c2 > 0 et n0 ≥ 0 telles que
c1 g(n) ≤ f (n) ≤ c2 g(n), pour tout n ≥ n0 . Ceci implique, par dénition même des classes
Ω(g(n)) et O(g(n)), que f (n) ∈ Ω(g(n)) et f (n) ∈ O(g(n)).
Soitf (n) ∈ Ω(g(n)) ∩ O(g(n)), ce qui implique qu'il existe c1 , c2 > 0 et n0 , n00 ≥ 0
0
telles que c1 g(n) ≤ f (n), pour tout n ≥ n0 et f (n) ≤ c2 g(n), pour tout n ≥ n0 . Il s'ensuit
0
que c1 g(n) ≤ f (n) ≤ c2 g(n), pour tout n ≥ max(n0 , n0 ). Ceci implique, par dénition
même de la classe Θ(g), que f ∈ Θ(g).

Exercice 4. Montrez que f (n) ∈ Ω(g(n)) si et seulement si f (n) ∈ O(g(n)) et


g(n) ∈ O(f (n)).

Exercice 5. Montrez que :

1. n log n ∈ O(n2 )
2. n(n + 1)/2 ∈
/ Θ(n)
3. n(n + 1)/2 ∈ Θ(n2 )
4. / Θ(n3 )
n(n + 1)/2 ∈
5. / Θ(n2 )
n log n ∈
6. 2n ∈ Θ(2n+1 )

Exercice 6. Evaluez la complexité moyenne de la recherche de l'élément maximal


dans un tableau de n entiers compris entre 1 et k.
1.6. CONCLUSION 17

Exercice 7. On suppose que a, b et k sont des entiers naturels. Montrez l'inégalité


suivante :  k
a+b
≤ ak + b k
2
En déduire que, pour k∈N et n ∈ N∗ , on a

f (n, k) = 1k + 2k + . . . + nk ∈ Θ(nk+1 )

Exercice 8. Le problème consiste à déterminer à partir de combien de mètres, un


objet construit avec un matériau spécial va se défragmenter si on le laisse tomber
en chute libre. On xe alors une hauteur maximale de n mètres et on se muni de k
exemplaires de l'objet en question. Un objet défragmenté ne peut, bien sur plus être
utilisé de nouveau. On se propose de concevoir un algorithme qui va déterminer la
hauteur fatale, (en mètre entier), en cassant le moins d'objets possible.
 Si k ≥ dlog2 ne, proposez un algorithme en O(log2 n) chutes libres.
n
 Si k < dlog2 ne, proposez un algorithme √
en O(k + 2k−1 ) chutes libres.
 Si k = 2, proposez un algorithme en O( n) chutes libres.

1.6 Conclusion

La rapidité des ordinateurs étant toujours tributaire de la technologie, elle sera toujours
limitée. Il est donc toujours protable de concevoir des algorithmes correctes et perfor-
mants. Comment doit-on alors procéder pour concevoir de tels algorithmes ? Les chapitres
qui vont suivre auront pour but de nous faciliter cette tâche.

1.7 Correction de quelques exercices

 Montrons que log n ∈ O(nε ), pour ε > 0. On doit donc montrer qu'il existe des
ε
constantes c ≥ 1 et n0 ≥ 0 telles que log n ≤ cn , pour tout n ≥ n0 .
1 ε
Prenons alors c = 1/ε et n0 = 1 et montrons que log n ≤ n , pour tout n ≥ 1.
ε
1 ε
Il s'agit donc de montrer que la fonction f (n) = n − log n est positive ou nulle,
ε
pour tout n ≥ 1.
0 nε −1
On a f (n) = , qui est positive ou nulle, pour tout n ≥ 1. Ceci implique que
n
f est une fonction croissante, pour tout n ≥ 1. De plus, on a f (1) = 1/ε ≥ 0. Il
1 ε
s'ensuit que f (n) ≥ 0, pour tout n ≥ 1, et par conséquent, log n ≤ n , pour tout
ε
ε
n ≥ 1. D'où log n ∈ O(n ).

 Montrons que (log n)k ∈ O(n), pour toute constante k ≥ 1. En un premier temps,
procédons par récurrence sur k pour montrer que l'appartenance est vraie pour tout
entier k ≥ 1. Pour k = 1, on a bien log n ≤ n, pour tout n ≥ 1. Donc log n ∈ O(n).
k k+1
Admettons que (log n) ∈ O(n) et montrons que (log n) ∈ O(n). Par hypothèse
k
de récurrence, il existe une constante ck > 0 telles que (log n) ≤ ck n, pour tout
n ≥ 1. Montrons qu'il existe aussi une constante ck+1 telles que (log n)k+1 ≤ ck+1 n,
18 CHAPITRE 1. COMPLEXITÉ DES ALGORITHMES

pour tout n ≥ 1. Pour ce faire, considérons alors la fonction

f (n) = ck+1 n − (log n)k+1

et montrons que f (n) ≥ 0, pour tout n ≥ 1.


On a
ck+1 n − (k + 1)(log n)k
f 0 (n) =
n
En utilisant (log n)k ≤ ck n, on obtient

f 0 (n) ≥ ck+1 − (k + 1)ck , ∀n ≥ 1

En prenant ck+1 = (k + 1)ck , on garantie que f 0 (n) ≥ 0. Donc, f (n) est fonction
croissante, pour tout n ≥ 1. De plus, f (1) = (k + 1)ck > 0. Il s'ensuit que f (n) est
positive quelque soit n ≥ 1. Enn, en tenant compte du fait que c1 = 1 et ck+1 =
(k + 1)ck , on déduit que (log n)k ≤ k!n, pour tout n ≥ 1. D'où (log n)k ∈ O(n),
pour tout entier k ≥ 1.
k dke
Pour les valeurs non entières de k , il sut de constater que (log n) ≤ (log n) ∈
O(n), pour tout n supérieur ou égal à la base du logarithme.

 Puisque le tableau contient une permutation des entiers de 1 à n,


la probabilité
1
que l'élément recherché soit dans la case i, 1 ≤ i ≤ n n
. Par ailleurs,
est égale à
quand l'élément se trouve dans la case i, l'algorithme de recherche séquentielle va
exécuter i opérations élémentaires. D'où la complexité moyenne de la recherche
séquentielle dans un tableau de taille n est donnée par :

n
1X
µ(n) = i
n i=1

n+1
On obtient µ(n) = 2
.


1.7. CORRECTION DE QUELQUES EXERCICES 19

Algorithme ChuteLibre1
Variables
n, k, h, deb, n : entier
début
Écrire(Donnez la hauteur maximale et le nombre d'objets)
répéter
Écrire(doivent être positifs)
Lire(n,k)
jusqu'à (n > 0 et k > 0)
si k < plafon(log(n)) alors
Écrire(Le nombre d'objets n'est pas susant)
sinon
deb := 1
n := n
tant que deb <= n faire
h := (deb+n) div 2
si Défrag(h) alors
n := h-1
sinon
deb := h+1
n
n
si n = n alors
Écrire(Augmentez la hauteur maximale)
sinon
Écrire(la hauteur fatale minimale est : , deb)
n
n
n
Algorithme 7 : Détermination de la hauteur critique pour tester la robustesse
d'un matériau en suivant une démarche dichotomique.
20 CHAPITRE 1. COMPLEXITÉ DES ALGORITHMES

Algorithme ChuteLibre2
Variables
n, k, h, deb, n : entier
début
Écrire(Donnez la hauteur maximale et le nombre d'objets)
répéter
Écrire(doivent être positifs)
Lire(n,k)
jusqu'à (n > 0 et k > 0)
deb := 1
n := n
tant que k > 1 et deb <= n faire
h := (deb+n) div 2
si Défrag(h) alors
n := h - 1
k := k - 1
sinon
deb := h + 1
n
n
tant que deb <= n faire
si Défrag(deb) alors
n := deb - 1
sinon
deb := h + 1
n
n
si n = n alors
Écrire(Augmentez la hauteur maximale)
sinon
Écrire(la hauteur fatale minimale est : , deb)
n
n
Algorithme 8 : Détermination de la hauteur critique pour tester la robustesse
d'un matériau en suivant une démarche hybride : dichotomique puis séquentielle.
1.7. CORRECTION DE QUELQUES EXERCICES 21

Algorithme ChuteLibre3
Variables
n, h, i : entier
stop : booleen
début
Écrire(Donnez la hauteur maximale)
répéter
Écrire(doit être positive)
Lire(n)
jusqu'à (n > 0)
etage := PartieEntière(RacineCarrée(n))
h := etage
stop:= faux
tant que h <= n et non stop faire
si Défrag(h) alors
stop := vrai
sinon
h := h + etage
n
n
si stop alors
i := h - etage + 1
tant que i < h et non Défrag(i) faire
i := i + 1
n
Écrire(la hauteur fatale minimale est : , i)
sinon
h := etage * etage + 1
tant que h <= n et non stop faire
si Défrag(h) alors
stop := vrai
sinon
h := h + 1
n
n
si stop alors
Écrire(la hauteur fatale minimale est : , h)
sinon
Écrire(Augmentez la hauteur maximale)
n
n
n
Algorithme 9 : Détermination de la hauteur critique pour tester la robustesse

d'un matériau en suivant une démarche par étage de taille n.

Vous aimerez peut-être aussi