Correction de la feuille de TD n˚3

publicité
Correction de la feuille de TD n˚3
MPSI option informatique
Exercice 1 : Sauf indication contraire, t désigne le nom d’un tableau (vecteur) et n un entier (indice).
1) Écrire une fonctions recevant comme argument t un tableau permettant de générer les valeurs de t. (0) , . . . , t. (n − 1),
où n est la longueur du tableau.
Correction : cf fichier Caml
2) Écrire une fonction recevant comme argument t et renvoyant le plus grand des éléments t (0) , . . . , t. (n − 1).
Évaluer le nombre de comparaisons effectuées.
Élaborer un algorithme qui trouve le plus grand et le plus petit des éléments t. (1) , . . . , t. (n) en effectuant un
nombre de comparaisons équivalent à 3n/2 (on pourra considérer les éléments deux par deux et commencer
par comparer deux éléments successifs).
Programmer une fonction mettant en œuvre cet algorithme.
Correction : cf fichier Caml
3) On veut mettre en œuvre l’algorithme de tri par insertion des valeurs t. (1) , . . . , t. (n) :
“pour k allant de 1 à n − 1, t. (k) est inséré à sa place dans le sous-tableau déjà trié t. (0) , . . . , t. (k − 1)”.
Formaliser cet algorithme, le prouver, puis évaluer sa complexité (en nombre de comparaisons).
Écrire une fonction recevant comme arguments t et renvoyant le tableau t trié grâce à l’algorithme ci-dessus.
Comment modifier cette fonction pour faire afficher le nombre de comparaisons effectuées ?
Correction : cf fichier Caml
4) Écrire et justifier une version récursive du tri par insertion.
Correction : cf fichier Caml
Exercice 2 : Programmer une fonction de fusion de deux segments de tableau adjacents triés en un segment
de tableau trié (on pourra utiliser un tableau auxiliaire).
En déduire un programme mettant en œuvre l’algorithme de “tri fusion” d’un tableau.
Correction : cf fichier Caml
Exercice 3 : Tri par fusion d’une liste :
1. Écrire une procédure de partage d’une liste en deux listes de tailles égales (éventuellement à 1 près !), puis
une fonction réalisant la fusion de deux listes triées.
2. En déduire un programme de tri par fusion d’une liste. En évaluer la complexité.
Correction : cf fichier Caml
Exercice 4 : Soit un tableau T de n entiers distincts, décrivez de manière précise un algorithme retournant
l’indice du minimum des éléments de T, basé sur la technique ”diviser pour régner”.
Correction : cf fichier Caml
1
Exercice 5 : Calcul des termes de la suite de Fibonacci.
La suite de Fibonacci est définie par les relations : F0 = F1 = 1 et pour tout n ≥ 0, Fn+2 = Fn+1 + Fn .
1) Ecrire un programme récursif calculant Fn pour n ≥ 0.
Correction : pas de nouveautés ! !
# let rec fibo n = match n with
| 0 −> 1
| 1 −> 1
| − > fibo (n-1) + fibo (n-2);;
Déterminer le nombre d’appels à la fonction selon n. On posera T(n) le nombre d’appels à la fonction pour
le calcul de Fn , puis on donnera une relation entre T 0 (n) = T (n) + 1, T 0 (n − 1) et T 0 (n − 2) pour n ≥ 2.
Correction : on a immédiatement que T (n) = 1 + T (n − 1) + T (n − 2) avec T (0) = T (1) = 1.
0
0
0
On en déduit que T 0 vérifie la récurrence dela suitede
Fibonacci
T (n −1) + T (n − 2), avec
: T (n) =
T 0 (0) = T 0 (1) = 2. On en déduit que T (n) =
√
5
5
+1
√
1+ 5
2
n
+
√
− 5
5
+1
√
1− 5
2
n
+ 1.
2) Ecrire un programme récursif calculant le couple (Fn−1 , Fn ).
Déterminer le nombre d’appels à la procédure selon n.
Correction :
# let fibo2 n =
let rec aux (a , b) n = match n with
dd| 1 -> (a,b)
dd| -> aux ( b , b + a ) (n-1);
in snd (aux (1,1) n);;
On a immédiatement n appels à la fonction.
3) Démontrer la relation : ∀(n, p) ∈ IN∗2 , Fn+p = Fn Fp + Fn−1 Fp−1 .
En déduire un programme de calcul de Fn selon la méthode ”diviser pour régner”.
Déterminer le nombre d’appels à la procédure selon n.
Correction : ce fait par récurrence double sur p (ou sur n).
Pour la fonction il faudra distinguer le cas n pair et n impair.
2
, F2n−1 = Fn−1 (2Fn − Fn−1 ) et F2n+1 = Fn (Fn + 2Fn−1 ).
On a en effet : F2n = Fn2 + Fn−1
On va encore calculer les couples Tn = (Fn−1 , Fn ).
2
2
, Fn (Fn + 2Fn−1 ) .
et T2n+1 = Fn2 + Fn−1
On a T2n = Fn−1 (2Fn − Fn−1 ), Fn2 + Fn−1
# let fibo3 n =
let rec aux n = match n with
dd| 0 − > (0,1)
dd| 1 − > (1,1)
dd| − > let (a,b) = aux (n/2) in
ddddif n mod 2 = 0 then (a*(2*b-a),a*a+b*b)
ddddddddelse (a*a +b*b, b*(b+2*a))
ddddin snd (aux n);;
Le nombre d’appel à la fonction vérifie Cn = 1 + Cbn/2c et C1 = 1, d’où Cn = 1 + blog2 (n)c
Exercice 6 : Une médiane d’un ensemble E de cardinal n est un élément m ∈ E tel que
jnk
Card {x ∈ E/x < m} =
2
1) Montrer l’unicité de la médiane d’un ensemble.
Correction : Pour m < m0 on a m ∈ {x ∈ E/x < m0 }, d’où
Card {x ∈ E/x < m} + 1 6 Card {x ∈ E/x < m0 }
On en déduit que Card {x ∈ E/x < m} + 1 6= Card {x ∈ E/x < m0 } et donc m et m0 ne peuvent être
simultanément médiane, d’où l’unicité.
2) Donner un algorithme de complexité Θ(n2 ) (mesurée en comparaisons) pour trouver la médiane d’un tableau.
Correction : On parcourt le tableau et, pour chaque élément, on compte
le nombre d’éléments qui lui sont
strictement inférieurs. On renvoie l’élément pour le quel ce nombre est n2 .
# let mediane t =
ddddlet n = vect length t and i = ref 0 and res = ref 0 and compte = ref 0 in
ddddwhile (!i < n) do
2
ddddddfor k = 0 to (n-1) do
ddddddddif t.(k) < t.(i) then compte:=!compte+1
dddddddone;
ddddddif !compte = n/2 then res :=1
ddddddelse compte := 0;
ddddddincr(i)
dddddone;
ddddt.(!res);;
3) Donner un algorithme de complexité Θ(n) (mesurée en comparaisons) pour trouver la médiane de deux
tableaux ordonnés de même longueur n.
Correction : on utilise la méthode diviser pour régner
# let rec mediane u v = match vect length u with
dddd| 1 -> max u.(0) v.(0)
dddd| n when n mod 2 = 1 -> if u.(n/2) v.(n/2) then
ddddddddmediane (sub vect u 0 (n/2+1)) (sub vect v (n/2) (n/2+1))
ddddddddddelse
ddddddddmediane (sub vect v 0 (n/2+1)) (sub vect u (n2) (n/2+1))
dddd| n -> if u.(n/2-1)>v.(n/2-1) then
ddddddddmediane (sub vect u 0 (n/2)) (sub vect v (n/2) (n/2))
ddddddddddelse
ddddddddmediane (sub vect v 0 (n/2)) (sub vect u (n/2) (n/2));;
Le nombre de comparaisons un pour des tableaux ordonnés de longueurs n vérifie un = ubn/2c + udn/2e + 1,
donc un = Θ(n).
3
Téléchargement