Exercices Ch2.mcw

publicité
EXERCICES SUR L’ALGORITHMIQUE ÉLÉMENTAIRE
Chapitre 2
Exercice 1
Soient A [1..m] et B [1..n] deux tableaux d’entiers. Les éléments de A sont tous distincts et
les éléments de B sont tous distincts, mais il peut y avoir des éléments communs entre A et B.
Esquisser quatre algorithmes efficaces en pire cas, deux se basant sur des techniques de tri et deux sur
des techniques de fouille, pour décider si chaque élément du tableau A se trouve quelque part dans le
tableau B. En considérant que les tableaux représentent des ensembles, vos algorithmes doivent donc
décider si A ⊆ B. Donnez les temps d’exécution de vos algorithmes en pire cas, simplifiés au
maximum, en fonction de m et de n (m ≤ n).
Solution
a) Premier algorithme basé sur une technique de tri.
1˚
Trier les éléments du tableau B [1..n]
O (n log n)
2˚
Rechercher dans B chaque élément de A en utilisant une recherche dichotomique.
O (m log n)
Total:
O (n log n).
Second algorithme basé sur une technique de tri
1˚ Transférer les éléments de A et de B dans un tableau C de longueur m+n.
O (m+n) (ou O(n) si on concatène B, de taille n, à A, inchangé)
2˚ Trier les éléments du tableau C
O ((m+n) log (m+n))
3˚ Calculer le nombre d’éléments de C répétés 2 fois; si cette valeur est égale à m alors A ⊆ B.
O (m+n)
Total:
O ((m+n) log (m+n))
(ou O (n log n) si m << n)
b) Premier algorithme basé sur une technique de fouille
1˚)
Construire un arbre AVL à partir du tableau B
O (n log n)
2˚)
Rechercher dans B (dans l’arbre AVL) chaque élément de A.
O (m log n)
Total:
Analyse d’algorithmes 2001
O (n log n) car m < n
EXERCICES SUR L’ALGORITHMIQUE ÉLÉMENTAIRE
1
Second algorithme basé sur une technique de fouille (utilise des résultats du chapitre 5)
1˚ Construire les monceaux A et B.
O (n)
2˚ TANT QUE non terminé FAIRE
SI le premier élément de A est égal au premier élément de B ALORS
Enlever le premier élément de A.
Enlever le premier élément de B.
SI A est vide ALORS Retourner {A ⊆ B} terminé.
SINON SI B est vide ALORS Retourner {A ⊄ B} terminé.
{SINON A ≠ Ø ≠ B: on boucle}.
SINON SI le premier élément de A est supérieur au premier élément de B ALORS
Retourner {A ⊄ B} terminé.
SINON {le premier élément de A est inférieur au premier élément de B}
Enlever le premier élément de B.
SI B est vide ALORS Retourner {A ⊄ B} terminé.
{SINON A ≠ Ø ≠ B: on boucle}.
FIN TANT QUE.
O (n log n)
Total:
O (n log n) car m < n
Exercice 2
Étant donnée une liste K de n clefs dans le désordre, vous devez produire une liste L des clefs
apparaissant en plus d’un exemplaire dans K. L’ordre des clefs dans la liste L est laissée à votre
entière discrétion, mais vous devez y éviter les répétitions.
Par exemple, étant donnée la liste
12 8 2 9 3 6 8
vous pouvez produire indifféremment
8 2 12 4
ou
mais pas
8 2 12
2 4 8 9 12
8 2 12 4 2
4 2 12 4 2 13
2 4 8 12
(4 se répète dans la liste originale)
(9 ne se répète pas dans la liste originale)
(2 est répété dans la liste produite)
Donnez deux algorithmes efficaces différents pour résoudre ce problème, l’un basé sur des
techniques de fouille (hachage) et l’autre basé sur des techniques de tri. Vous pouvez supposer que
des procédures de fouille et de tri sont déjà disponibles. Analysez le temps d’exécution de vos
algorithmes en moyenne et en pire cas.
Exercice 3
En étudiant le problème de la multiplication de grands entiers, nous avons montré que
l’algorithme de multiplication à la russe, si l’on considère les opérandes comme de grands entiers,
s’exécute en un temps dans l’ordre de (m+p) p bits (ou mots-machine). Précisez cela en détaillant ce
qui se passe à chaque itération. Quelle différence cela entraîne-t-il selon que le multiplicateur est le
plus petit ou le plus grand des deux opérandes? Comparez ces résultats à l’efficacité des deux autres
algorithmes de multiplication de grands entiers.
2
EXERCICES SUR L’ALGORITHMIQUE ÉLÉMENTAIRE
©2001 R. Lelouche
Solution
Rappelons que, comme on travaille avec de grands entiers, on ne peut pas considérer une
addition ou une multiplication comme une opération élémentaire. Concernant les multiplications ou
divisions par deux, même si elles devaient se traduire par des décalages, ceux-ci devraient être
propagés de mot en mot, et donc prendre un temps linéaire par rapport à la taille (nombre de mots, de
chiffres, ou de bits) des grands entiers en question, comme toute autre addition ou multiplication. La
seule chose favorisant ces «décalages étendus» est que la constante multiplicative (temps par motmachine) a des chances d’être plus faible pour les décalages que pour les additions (et plus faible pour
les additions que pour les multiplications quelconques d’un mot ou chiffre par un autre). Dans le
raisonnement qui suit, nous exprimons la taille en bits, plus faciles à appréhender, plutôt qu’en mots,
d’autant plus que c’est ainsi qu’a été présenté l’algorithme.
La ie itération (remplissage de la ie ligne du tableau), dans la colonne du multiplicande A, calcule
un produit partiel double de celui calculé à la ligne précédente, donc ayant un bit de plus. Comme au
départ le multiplicande comporte m bits, cette ie itération calcule un produit partiel de m + i bits (ou
mots). Elle prend par conséquent un temps dans l’ordre de m + i. Puisque le multiplicateur B, qui
diminue d’un bit à chaque itération, comprend au départ p bits ou mots, il y a p itérations au total. La
succession de ces p itérations prend donc un temps
T (m, p) = m + (m + 1) + (m + 2) + ... + (m + p – 1)
p–1
=mp+
p
≈ p (m + 2 )
∑ i = m p + p (p–1)
2
(1)
i=1
Si on prend comme multiplicateur B le plus petit des deux opérandes (p < m), le terme dominant
de la parenthèse est m, d’où un temps global dans l’ordre de p m. C’est dans le même ordre que pour
l’algorithme classique, mais avec une constante multiplicative risquant d’être plus grande (p. ex., si B
est le multiplicateur, il y a lgB itérations dans l’algorithme à la russe au lieu de log 10B itérations dans
l’algorithme classique, soit lg10 fois plus).
Si on prend comme multiplicateur B le plus grand des deux opérandes (p > m), le terme
p
dominant de la parenthèse est 2 , d’où un temps global dans l’ordre de p2. Cela est plus mauvais que
pour l’algorithme classique, puisque l’algorithme est alors quadratique par rapport à la taille du plus
grand opérande (au lieu d’être le produit des deux tailles)!
Remarque. Dans le raisonnement qui précède, on s’est concentré sur le calcul des produits
partiels successifs (colonne du multiplicande A). Alternativement, on pourrait prendre en compte
aussi le temps de calcul des multiplicateurs successifs. Cela serait tout-à-fait justifié, puisque ces
multiplicateurs successifs sont aussi de grands entiers, bien que leur taille diminue de p à 1. Dans ce
cas, à la sommation (1) ci-dessus des produits partiels s’ajouterait une sommation
p–1
T1 (p)
= (p – 1) + (p – 2) + ... + 1 =
p
≈ p (2 )
∑ i = p (p–1)
2
(2)
i=1
due aux multiplicateurs successifs qui vont en diminuant. La prise en compte de cette seconde comp
posante aurait comme seul effet, en bout de ligne, de remplacer dans (1) la parenthèse (m + ) par
2
(m + p), et les conclusions ci-dessus (selon les tailles respectives de A et B) subsisteraient.
Analyse d’algorithmes 2001
EXERCICES SUR L’ALGORITHMIQUE ÉLÉMENTAIRE
3
Téléchargement