La dichotomie ne sert pas qu'aux tableaux
Exercice supplémentaire · niveau 3 (difficile) · NSI (première), chapitre 8 — Dichotomie, voisins et gloutons · Le défaut de 2006, et la dichotomie ailleurs
Énoncé
La dichotomie ne sert pas qu'aux tableaux. L'utiliser pour calculer une racine carrée sans **0.5, en cherchant le point où la fonction franchit la valeur visée. Quel est le variant ?
Corrigé
def racine_carree(x, precision=1e-12):
"""Racine carree de x par dichotomie. Precondition : x >= 0.
Variant : la largeur de l'intervalle, DIVISEE PAR DEUX a chaque tour.
"""
assert x >= 0
gauche, droite = 0, max(1, x) # max(1, x) couvre le cas 0 < x < 1
tours = 0
while droite - gauche > precision:
milieu = (gauche + droite) / 2
if milieu * milieu < x:
gauche = milieu
else:
droite = milieu
tours += 1
return (gauche + droite) / 2, tours
for x in [0, 1, 2, 9, 1e6]:
r, _ = racine_carree(x)
assert abs(r - x ** 0.5) < 1e-6
r, tours = racine_carree(2)
assert abs(r - 2 ** 0.5) < 1e-9
assert tours == 41
Le variant n'est plus entier, et cela change tout au raisonnement. La largeur de l'intervalle est un flottant, qui est divisé par deux à chaque tour ; il ne peut donc pas « atteindre zéro » comme un compteur d'indices. Ce qui garantit l'arrêt, c'est qu'il devient inférieur à la précision demandée au bout d'un nombre fini de tours — ici, pour à partir d'un intervalle de largeur , puisque .
Le max(1, x) est la seule subtilité. Pour , la racine est plus grande que : chercher dans ne la trouverait jamais. Le cas racine_carree(0.25) — dont la réponse est — est exactement celui qu'un test rapide sur des entiers ne révélerait pas.
La même méthode résout n'importe quelle équation monotone. Il suffit de remplacer milieu <em> milieu < x par la condition voulue : la dichotomie ne cherche pas « dans un tableau », elle cherche un point de bascule*. C'est l'objet de l'exercice C9.
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.