Académique Documents
Professionnel Documents
Culture Documents
Définition 1.1 Une boucle est une construction algorithmique qui permet d’exécuter de
manière répétitive une instruction ou une suite d’instructions.
Boucle Pour
Ceci s’applique lorsqu’on connaît à l’avance le nombre d’exécutions et les éléments qui
seront traités. L’instruction est exécutée pour les valeurs de l’indice allant de
Valeur_Initiale à Valeur_Finale
Pour concevoir un algorithme basé sur une boucle pour la résolution d’un problème, il
est conseillé de commencer par bricoler sur un petit exemple en respectant la structure
suivante :
La forme générique d’un algorithme basé sur une boucle est donc la suivante
On désire déterminer le plus petit indice i correspondant à une occurrence de val dans un
vecteur V[1..n]. Une variable booléenne trouvé, indiquera si une telle occurrence existe.
L’algorithme est le suivant :
Dans cet algorithme, la condition de sortie comporte un test sur trouve et un test
sur i. On peut économiser l’un de ces tests en utilisant une sentinelle comme
indiqué ci-dessous, où on désire déterminer le plus grand indice i correspondant à une
occurrence de val dans un vecteur V[1..n]. Une variable booléenne trouvé, indiquera si une
telle occurrence existe.
L’idée est de placer la valeur cherchée val dans la position où l’on se retrouvera
si elle n’est pas dans V[1..n], c-à-d en position 0. On est alors certain de trouver val
soit dans une position i > 0, ce qui correspond à trouve = vrai,
soit en position i = 0, ce qui correspond à trouve = faux.
Exercice 1.2
1.2.a Montrer que la comparaison lexicographique entre deux vecteurs V[i..j] et W[i..j]
peut se ramener à un problème de recherche que l’on précisera
1.2.b Donner l’algorithme correspondant à la question 1.2.a.
1.2.3 Donner un algorithme qui cherche dans un vecteur W[1..n], un sous-vecteur W[i..i+n-1]
égal à V[1..n].
Exercice 1.3
Donner un algorithme qui fusionne deux vecteurs triés U[1..n] et V[1..m] en un vecteur trié
W[1..n+m].
Indication : Une solution simple comporte trois boucles
Exercice 1.4
Donner un algorithme qui imprime ligne par ligne, les éléments d'une matrice triangulaire
inférieure d’ordre n.
1.6.2 Compléter l’algorithme ci-dessous pour la résolution d’un système triangulaire obtenu à
la question précédente.
xn := … ;
Pour i := … à … faire
Calcul de xi
début
xi := … ;
Pour j := … à … faire xi := xi - … ;
xi := … ;
fin
Problème A (Tri d’un vecteur)
On considère un vecteur V[1..n].
A.1 Compléter la procédure Select_Max ci-dessous, qui sélectionne le maximum de V[1..i] et
le met en position i par permutation avec V[i].
A.2 Compléter la procédure Tri_Select_Max ci-dessous, qui trie un vecteur V[1..n] dans
l’ordre croissant.
On suppose dans la suite que V[1..n] est un vecteur d’enregistrements représentant les
résultats d’examen, et de type indiqué ci-dessous
Record
Nom : char(10)
Note : integer
end ;
Au départ, les enregistrements sont triés par ordre alphabétique des noms. Après saisie des
notes, les résultats doivent être triés par ordre de mérite.
Un algorithme de tri est dit stable s’il préserve l’ordre des éléments ex-aequo. Autrement dit,
à partir d’un fichier trié par ordre alphabétique, deux étudiants ayant la même note doivent
après le tri, apparaître dans l’ordre alphabétique.
Les algorithmes vus jusqu’ici construisent au fur et à mesure des sous-vecteurs triés V[i..n] de
plus en plus grands, c-à-c correspondant 0 des valeurs décroissantes de i.
On s’intéresse maintenant au tri par insertion qui construit au fur et à mesure des sous-
vecteurs triés V[1..i] de plus en plus grands.
A.11 Compléter la procédure Insertion ci-dessous qui, à partir d’un sous-vecteur trié V[1..i-1],
crée un vecteur trié V[1..i], par insertion de V[i, en faisant des comparaisons-échanges V[i-
1]V[i], V[i-2] V[i], V[i-3] V[i], …. BV noter la présence de la position sentinelle 0.
A.12 Déduire une procédure Tri_Insertion pour le tri d’un vecteur V[1..n].
On se propose maintenant d’analyser les performances des algorithmes de tri qui effectuent
des comparaisons uniquement entre des éléments consécutifs V[i] V[i+1].
A.14 Montrer que dans un tel algorithme, deux éléments initialement situés en positions i, j
avec i < j, et qui à la fin se retrouvent respectivement dans les positions r, s, r > s, ont
forcément fait l’objet d’une comparaison-échange au cours de l’exécution.
Nous nous intéressons maintenant au nombre moyen d’inversions d’une permutation. A cet
effet, on considère l’ensemble des vecteurs correspondant aux permutations de n éléments
distincts notés e1, e2, … , en, muni de la loi uniforme. Pour une permutation particulière, on
note Ni le nombre d’inversions ayant pour élément de gauche ei.
A.18 Montrer que sur l’ensemble des permutations, Ni est une variable aléatoire uniforme, c-
à-d la probabilité qu’une permutation ait k inversions, k [0, i-1], est 1/i.
Indication : Compter le nombre de permutations telles que Ni = k, et diviser par le nombre
total des permutations.
A.19 Déduire que le nombre moyen d’inversions d’une permutation d’ordre n est n(n-1)/2.
Ceci montre qu’un algorithme qui effectue des comparaisons uniquement entre des éléments
consécutifs V[i] V[i+1], a une performance en moyenne qui est en O(n2).
Pour faire mieux, il faut donc effectuer des comparaisons-échanges entre éléments non
consécutifs. Pour exploiter cette idée on décide de décomposer V en sous-vecteurs ayant des
éléments espacés de k ainsi qu’il suit :
V[1], V[1+k], V[1+2k], … ,
V[2], V[2+k], V[2+2k], … ,
…
V[k-1], V[k-1+k], V[k-1+2k], … ,
V[k], V[2k], V[3k], … ,
A.21 Expérimenter cet algorithme par exemple pour n = 10000, ainsi qu’il suit :
1. Considérer plusieurs valeurs de k (10, 20, 30, … 100)
2. Pour chaque valeur de k, exécuter l’algorithme sur 10000 permutations tirées au hasard
et déterminer le nombre moyen de comparaisons-échanges par permutation
3. Tracer la courbe obtenue pour le nombre de comparaisons-échanges, en fonction de k
A.22 Retrouver dans la littérature, des travaux sur la mise en œuvre de l’algorithme ci-dessus.
On s’intéresse maintenant au tri d’une file séquentielle qu’on peut assimiler à une suite
mathématique. A cet effet on utilisera le répertoire d’instructions du tableau ci-dessous.
A.23 Donner une procédure Extraction_Monotonies ci-dessous qui, partant d’une file F = (a1,
… , an), crée deux files F1 et F2 contenant alternativement les monotonies (sous-suites
monotones croissantes maximales) de F ainsi qu’il suit :
première monotonie dans F1
deuxième dans F2
troisième dans F1
quatrième dans F2
…
monotonie de rang 2i-1 dans F1
monotonie de rang 2i dans F2
…
A.24 Donner une procédure Fusion_Monotonies qui à partir de deux files F1 et F2, crée une
file F par fusion des monotonies de même rang dans F1 et F2 ainsi qu’il suit :
fusionner la 1ère monotonie de F1 et la 1ère monotonie de F2 avec insertion dans F
fusionner la 2ème monotonie de F1 et la 2ème monotonie de F2 avec insertion dans F
…
fusionner la ième monotonie de F1 et la ième monotonie de F2 avec insertion dans F
…
Dès que l’une des files F1 ou F2 est épuisée, le reste de l’autre file est recopié dans F.
A.25 Déduire une procédure Tri_Fusion_Monotonies pour le tri de F, qui procède ainsi qu’il
suit :
<Initialisations>
Jusqu’à <F est triée> faire
début
Extraction_monotonies (F, F1, F2) ;
Fusion_Monotonies (F1, F2, F)
fin
A.26 Montrer que le temps d’exécution de cet algorithme est O(n log2 n).
On considère maintenant le tri de vecteurs dont les éléments appartiennent à un type énuméré,
par exemple a, b, c, … , z, pouvant être utilisé pour indicer un vecteur.
A.27 Donner une procédure de calcul des fréquences Freq[a..z] des éléments de V[1..n].
Les boucles sont les constructions algorithmiques les plus délicates, et il est important de
s’assurer qu’elles sont correctes. Ceci nécessite de montrer que la boucle a les deux propriétés
suivantes :
Terminaison : La boucle doit se terminer, c-à-d produire un résultat en temps fini
quelles que soient les données fournies en entrée.
Correction partielle : Lorsque la boucle s’arrête, le résultat produit doit être la
solution cherchée quelles que soient les données fournies en entrée.
Autrement dit une boucle est correcte si, quelles que soient les données fournies en entrée,
elle s’arrête et fournit la solution cherchée. On résume cela par la formule suivante :
A noter qu’il existe des problèmes pour lesquels il n’existe que des algorithmes partiellement
corrects, c-à-d dont on n’a pas démontré la terminaison. Le lecteur est invité à en rechercher
un dans la littérature scientifique.
Définition 1.2 Un variant est une quantité positive qui décroit strictement à chaque passage
dans la boucle. Un variant est donc une expression impliquant des variables qui interviennent
dans l’exécution de la boucle.
est basée sur une propriété P qui doit être vérifiée après exécution de la boucle et qui
correspond à l’équation :
P = <Invariant> et <Condition_d’arrêt>
La forme générique d’un fragment de programme construit autour d’une boucle s’écrit alors
comme suit :
<Initialisation qui garantit l’invariant>
{<Enoncé de l‘invariant>}
{<Enoncé du variant>}
Jusqu’à <Condition d’arrêt> faire
début
<Actions qui font progresser le calcul, réduisent le variant et
maintiennent l’invariant >
fin ;
{<Propriété cherchée> = <Invariant> et <Condition d’arrêt>}
<Action qui finalise la tâche à réaliser >
Exemple 1.1 Recherche dichotomique dans un vecteur trié par ordre croissant
Exemple 1.4 Algorithme d’Euclide pour le calcul du pgcd de deux nombres positifs.
La solution est basé sur les propriétés suivantes :
Si x > 0 alors pgcd (x, 0) = x
Si x > 0 et y > 0, x alors pgcd(x, y) = pgcd (y, r) où r est le reste de la division de x par
y.
On précisera les éléments suivants : invariant, variant, condition de sortie, condition
finale.
On considère le tri d’un vecteur V[1..n] dont les éléments ont trois valeurs possibles : vert,
rouge et jaune. On considère un algorithme basé sur l’invariant suivant : chacun des indices i,
j et k indique respectivement la position où placer le prochain élément vert, rouge ou jaune.
1.5.1 Faire un dessin pour bien visualiser cet invariant
1.5.2 Quelle est à chaque instant, la partie du vecteur qui est non triée ?
1.5.3 Compléter l’algorithme ci-dessous
1. i := … ; j := n ; k := … ;
2. Jusqu’à … faire
Si V[i] = vert alors i := … sinon
Si V[i] = rouge alors début Echanger (V[i], V[j]) ; j := … fin sinon
Si V[i] = jaune alors
Permutation circulaire de V[i], V[k] et V[j], V[j]
début
Echanger (V[i], V[j]) ;
Echanger (V[j], V[k]) ;
j := j-1
fin ;
Exercice 1.6