La dichotomie entière qui ne se termine pas
Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 15 — Diviser pour régner
Énoncé
Le cours avertit que la dichotomie flottante ne peut pas s'arrêter sur une égalité. Sur les entiers, une autre boucle infinie guette. Laquelle ?
Corrigé
Voici la recherche d'un seuil sur les entiers, telle qu'on l'écrit spontanément — étant une propriété monotone, fausse puis vraie :
(* FAUX : ne termine pas. *)
while !bas < !haut do
let m = (!bas + !haut) / 2 in
if p m then haut := m else bas := m (* <-- bas := m *)
done
Mesuré sur dans : la boucle atteint l'état , , et y reste. En effet par troncature, est faux puisque , donc : rien n'a bougé, et le tour suivant est identique. L'exécution a été arrêtée à cent tours.
Le diagnostic. La division entière tronque vers le bas : quand , le milieu vaut . L'affectation bas := m ne change alors rien, et le variant cesse de décroître.
La correction — une unité :
(* Plus petit n de [bas, haut] tel que p n, en supposant p monotone et p haut vrai.
Complexité : Theta(log (haut - bas)). *)
let cherche_seuil p bas0 haut0 =
let bas = ref bas0 and haut = ref haut0 in
(* INVARIANT : le seuil est dans [bas, haut]. *)
while !bas < !haut do
let m = !bas + (!haut - !bas) / 2 in
if p m then haut := m else bas := m + 1 (* +1 : m est ÉLIMINÉ *)
done;
!bas
Elle rend en tours, et l'on vérifie .
Le raisonnement qui l'aurait évitée. Écrire le variant avant le code. Le variant est ; pour qu'il décroisse strictement, il faut que chaque branche élimine au moins une valeur. Si est faux, alors n'est pas le seuil : on peut, et l'on doit, l'éliminer — d'où . Si est vrai, est un candidat qu'il faut garder : , et c'est le choix de la troncature vers le bas qui rend cette branche sûre.
La règle générale, et elle se retient. Dans une dichotomie entière, la branche qui garde le candidat doit être celle vers laquelle la division tronque. Ici la troncature va vers le bas, donc c'est haut qui garde. Si l'on cherchait le plus grand tel que , il faudrait arrondir le milieu vers le haut, sans quoi la même boucle infinie reviendrait de l'autre côté.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.