Cours d’algorithmique
IPT Deuxième année
1. Qu’est-ce qu’un algorithme ? [FYO337]
Définitions
Définition 1
De façon informelle, un algorithme est une méthode de calcul bien définie qui permet
de résoudre une famille de problèmes. Il prend une valeur ou un ensemble de valeurs
en entrée et produit une valeur ou un ensemble de valeurs en sortie.
EXEMPLE 1 (PROBLÈME DU TRI)
Entrée : Une liste de nnombres [t0,t1,...,tn1].
Sortie : Une permutation [t
0,t
1,...,t
n1]de la liste en entrée telle que
t
0t
1··· t
n1.
Si la liste en entrée est [31,41,59,26,41,58], l’algorithme de tri retournera
comme liste de sortie [26,31,41,41,58,59].
Définition 2
Une entrée particulière de l’algorithme est appelée une instance du problème.
Définition 3
Un algorithme est correct si, pour chacune des instances du problème, l’algorithme
s’arrête et retourne la sortie attendue.
Définition 4
Un problème est calculable s’il existe au moins un algorithme correct pour le ré-
soudre.
L’algorithme peut être spécifié en français ou dans un langage de programmation.
La seule exigence est que la spécification fournisse une description précise des
calculs à effectuer.
Efficacité
Définition 5
Pour un problème algorithmique donné, il est utile de définir la notion de taille d’une
instance.
Si les instances sont des nombres entiers, ce peut être ce nombre entier. Il
peut cependant être plus pertinent de compter le nombre de chiffres binaires
nécessaires pour écrire cet entier.
Si les instances sont des listes d’objets, la taille d’une instance correspondra au
nombre d’éléments dans cette liste.
Pour la plupart des algorithmes, le temps d’exécution dépend essentiellement de
la taille de l’instance.
Un algorithme doit non seulement être correct mais il doit aussi être efficace pour
être utilisable en pratique.
http://docs.dichotomies.fr/2014/informatique/ipt2/cours/algorithmique/
Denis Pinsard – Mis à jour le lundi 25 août 2014
[PVT856]
EXEMPLE 2
On dispose d’une machine M1capable d’exécuter 107instructions par seconde et
d’une machine M2capable d’exécuter 109instructions par seconde.
On considère un certain problème nest la taille des instances.
On dispose d’un algorithme A1qui résout le problème en 2n2instructions et d’un
algorithme A2qui résout le problème en 50nlog ninstructions.
Comparons les temps de calculs selon la machine, l’algorithme et la taille de
l’instance.
n=100 Nombre d’instructions Temps machine M1Temps machine M2
Algorithme A120 000 instructions 2 millisecondes 0,02 millisecondes
Algorithme A230 000 instructions 3 millisecondes 0,03 millisecondes
n=106Nombre d’instructions Temps machine M1Temps machine M2
Algorithme A12000 ×109instructions 200 000 secondes 2000 secondes
Algorithme A2109instructions 100 secondes 1 seconde
Nous constatons en particulier que pour n=106l’algorithme A2est 2 000 fois
plus rapide que l’algorithme A1. Il gagne donc largement, même si on l’exécute
sur une machine 100 fois plus lente.
Représentons graphiquement les évolutions du nombre d’instructions en fonction
de n.
0 20 40 60 80 100
n
2n2
50nlog(n)
Croissances compar´ees du nombre
d’instructions pour n<100
0 200 400 600 800 1000
n
2n2
50nlog(n)
Croissances compar´ees du nombre
d’instructions pour n<1000
La croissance en nlog nressemble beaucoup en pratique à une croissance linéaire
et se révèle nettement avantageuse pour de grandes valeurs de n.
L’exemple précédent met en évidence quelques éléments importants :
Pour de grandes valeurs de nl’élément décisif est le comportement en
nlog(n)versus le comportement en n2. La valeur du coefficient multipli-
catif (50 au lieu de 2) n’est pas essentiel.
Plus nest grand et plus l’écart de performance entre les algorithmes se
manifeste.
Les progrès technologiques du matériel ne permettent pas de compenser
l’inefficacité de certains algorithmes.
2. Tri par insertion [SPB971]
http://docs.dichotomies.fr/2014/informatique/ipt2/cours/algorithmique/
Denis Pinsard – Mis à jour le lundi 25 août 2014
[PVT856] Page 2
Présentation
Nous revenons dans ce chapitre sur le problème du tri :
Entrée : Une liste de nnombres [t0,t1,...,tn1].
Sortie : Une permutation [t
0,t
1,...,t
n1]de la liste en entrée telle que
t
0t
1··· t
n1.
L’algorithme du tri par insertion correspond à la façon dont la plupart des per-
sonnes rangent leur main lorsqu’elles jouent aux cartes. Les cartes du joueur sont
empilées sur la table devant lui. Il prend alors une carte à la fois sur la table et
l’insère à la bonne place dans sa main. Pour trouver cette place, il la compare
avec chacune des cartes déjà dans sa main, en les parcourant de la droite vers
la gauche. À chaque instant, les cartes qui sont dans sa main sont correctement
rangées.
Cet algorithme peut être décrit plus formellement par le pseudo-code suivant :
✞ ☎
1Algorithme TriInsertion(T)
2j1
3Tantque j<T.longueur faire
4clé T[j]
5// Insertion de T[j]dans la liste ordonnée T[0 : j].
6ij1
7Tantque i¾0et T[i]>clé faire
8T[i+1]T[i]
9ii1
10 finTantque
11 T[i+1]clé
12 jj+1
13 finTantque
✝ ✆
Le pseudo-code est une façon de décrire très précisément un algorithme, en évi-
tant les ambiguités. Cela ressemble à du code dans un langage de programmation.
Toutefois ce texte n’est pas destiné à être interprété directement par une machine.
Il peut en particulier contenir du texte en français si cela se révèle utile pour la
compréhension.
Quelques remarques pour bien comprendre ce pseudo-code :
Une ligne qui débute par « // » n’est pas une instruction mais un commen-
taire. Elle fournie une explication sur les instructions qui suivent.
Tdésigne un tableau de nombres.
T[0]est le premier nombre du tableau.
T.longueur est le nombre d’élément dans le tableau.
Le dernier élément est donc T[T.longueur 1].
T[a:b]désigne le sous-tableau des indices itels que ai<b.
Vous ne devriez pas être troublés par ces conventions qui sont celles du langage
Python (hormis la notation pour la longueur du tableau).
Le tableau Test l’entrée de l’algorithme, mais c’est aussi la sortie. L’algorithme
tri le tableau T en place. Cela signifie qu’il réarrange les valeurs du tableau en ne
copiant à l’extérieur de celui-ci qu’un nombre fixé de valeurs, indépendant de la
taille du tableau.
http://docs.dichotomies.fr/2014/informatique/ipt2/cours/algorithmique/
Denis Pinsard – Mis à jour le lundi 25 août 2014
[PVT856] Page 3
Correction de l’algorithme
L’algorithme TriInsertion présenté ci-dessus résout-il correctement le problème
du tri. La concept d’invariant de boucle va permettre de nous en convaincre.
Considérons la proposition suivante :
Au début de chaque itération (juste avant le test de la ligne 3), le sous-tableau
T[0 : j]est constitué des éléments qui étaient à l’origine dans T [0 : j], mais triés
par ordre croissant.
Cette proposition est appelée un invariant de boucle.
On démontre cette proposition en montrant trois choses :
Initialisation : La proposition est vraie au début de la première itération.
Maintenance : Si la proposition est vraie au début d’une itération, elle reste
vraie au début de l’itération suivante.
Terminaison : La condition d’arrêt de la boucle finie par être satisfaite.
L’invariant de boucle associé à la condition d’arrêt nous donnent alors une aide
précieuse pour démontrer que l’algorithme est correct.
Appliquons cette démarche à notre algorithme.
Initialisation : Au début de la première itération on a j=1, donc T[0 : j]
ne contient que l’élément T[0]qui est le premier élément du tableau initial.
L’invariant de boucle est donc clairement vrai à la première itération.
Maintenance : La boucle intérieure (lignes 7-10) a pour effet de déplacer d’une
position les éléments de T[0 : j]qui sont strictement supérieurs à T[j]. La
valeur T[j]est ensuite copiée dans la position libérée (ligne 11). Le sous-tableau
T[0 : j+1]contient alors les éléments du sous-tableau T[0 : j+1]initial, mais
triés par ordre croissant. L’incrémentation de j(ligne 12) rétablit alors l’invariant
de boucle.
Terminaison : Puisque jest incrémenté à chaque itération, la condition j=T.longueur
finie nécessairement par être satisfaite, ce qui met fin à la boucle.
Ceci prouve que l’algorithme se termine avec l’invariant de boucle et la condition
j=T.longueur satisfaient tous les deux. Nous en déduisons alors que le sous-
tableau T[0 : T.longueur], autrement dit le tableau Tcomplet, est constitué
des éléments qui étaient à l’origine dans T[0 : T.longueur](c’est-à-dire T),
mais triés par ordre croissant. Nous en concluons que l’algorithme TriInsertion
résout correctement le problème du tri.
Temps d’exécution de l’algorithme
Le temps d’exécution d’un algorithme dépend bien entendu de la machine sur la-
quelle il s’exécute. Pour évaluer ce temps d’exécution, nous devons disposer d’un
modèle de machine. Le modèle de machine que nous considérons pour évaluer
le temps d’exécution est la machine RAM (Random Access Memory), modèle sur
lequel repose la très grande majorité des ordinateurs :
Les instructions de la machine sont les opérations élémentaires sur les
nombres (addition, soustraction, multiplication, division, reste), le dépla-
cement d’octets (ou de mots formés de quelques octets), les instructions de
contrôle (branchement conditionnel ou inconditionel, appel de sous pro-
gramme).
Les instructions sont exécutées les unes après les autres, il n’y a pas de
parallélisme.
Chaque instruction nécessite un temps constant.
http://docs.dichotomies.fr/2014/informatique/ipt2/cours/algorithmique/
Denis Pinsard – Mis à jour le lundi 25 août 2014
[PVT856] Page 4
Nous évaluerons le temps d’exécution Ten fonction de la taille nde l’entrée,
c’est-à-dire du nombre d’éléments qui constituent cette entrée. Par élément nous
entendons une donnée élémentaire (un octet ou un mot de quelques octets) qui
peut être déplacée en un temps constant par la machine.
Le temps d’exécution T(n)sera exprimé en nombre d’instructions élémentaires.
Dans la majorité des cas, chaque ligne de l’algorithme correspondra à une ins-
truction élémentaire.
Deux instances de même taille nn’engendrent pas nécessairement le même temps
d’exécution. Nous distinguerons donc :
Tb(n), le temps d’exécution dans le meilleur des cas ;
Tw(n), le temps d’exécution dans le pire des cas.
Tw(n)est donc le plus long temps d’exécution pour une instance de taille n.
Si nous faisons une hypothèse sur la distribution des instances fournies en entrée
de l’algorithme, nous pouvons également calculer le temps d’exécution moyen
Tm(n).
Pour l’algoritmme TriInsertion, nous avons calculé en exercice :
Tb(n) = 6n4, Tw(n) = 3
2n2+9
2n4 et Tm(n) = 3
4n2+21
4n4.
Tm(n)a été calculé en faisant l’hypothèse d’une distribution uniforme des ins-
tances de taille n.
Lorsque nous calculerons un temps d’exécution nous calculerons de préférence
Tw(n). En effet :
Tw(n)nous donne une majoration du temps d’exécution de n’importe quelle
instance de taille n.
Dans certains algorithmes, le pire des cas est souvent un cas courant. Pensez
par exemple à la recherche dans une base de données lorsque la donnée est
absente.
Le « cas moyen » est souvent quasi aussi mauvais que le pire cas comme le
montre l’exemple de l’algorithme TriInsertion.
Complexité temporelle de l’algorithme
Lorsque nous analysons le temps d’exécution d’un algorithme nous nous inté-
ressons essentiellement au comportement pour de grandes valeurs de n, autre-
ment dit au comportement asymptotique lorsque n+. Pour l’algorithme
TriInsertion on a :
Tb(n)6net Tw(n)3
2n2.
De plus, les coefficients 6 et 3
2n’étant pas très significatifs, nous écrirons plutôt
Tb(n) = Θ(n)et Tw(n) = Θ(n2),
et nous dirons que la complexité temporelle de l’algorithme TriInsertion dans
le meilleur des cas (respectivement dans le pire des cas) est linéaire (respective-
ment quadratique).
Lorsqu’un algorithme s’exécute en un temps indépendant de la taille ndes ins-
tances en entrée, on note sa complexité Θ(1).
La notation Θest étroitement liée à la notation Ode Landau. Plus précisément,
si fet gsont deux fonctions de n:
f(n) = Θ g(n)f(n) = Og(n)et g(n) = Of(n).
http://docs.dichotomies.fr/2014/informatique/ipt2/cours/algorithmique/
Denis Pinsard – Mis à jour le lundi 25 août 2014
[PVT856] Page 5
1 / 6 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !