Travail Dirigé 1 - Dichotomie pour Racines et Logarithmes
Le jour de l’examen, vous commencerez par avoir du temps pour réfléchir et poser vos idées sur papier avant de passer sur machine. Vous devez donc pratiquer cette approche.
Au-delà de l’aspect préparation à l’examen, il s’agit d’une pratique importante qui permet de prendre du recul par rapport à des problématiques de développement logiciel. Plutôt que de tenter d’écrire directement un programme sur machine, prendre le temps de noter ses réflexions permet souvent de trouver de meilleures solutions.
Dans le cadre de ce premier TD, vous allez donc écrire vos premiers programmes Python sur papier.
Exercice 1 - Calcul d’un racine carrée par énumération dans un espace de solutions
Ecrivez un script en Python qui calcule une racine carrée en énumérant une suite de solutions.
Le nombre est obtenu via la fonction input
et le résultat , s’il est trouvé, est affiché dans la sortie standard avec print
. Sinon, le message d’erreur suivant est affiché : "Erreur : la racine carrée de {N} n'a pas été trouvée"
.
L’algorithme suit les étapes suivantes :
- On lit la valeur rétournée par
input
, qui est convertie enfloat
. - On initialise à
0
. - On initialise à
0.01
. - Dans une boucle :
- Si , alors la boucle s’arrête et on affiche le résultat .
- Si , alors la boucle s’arrête et le message d’erreur est affiché.
- Sinon, on incrémente de et on poursuit la recherche.
Exercice 2 - Calcul d’une racine carrée en utilisant la dichotomie
Ecrivez un script qui calcule une racine carrée en utilisant la dichotomie.
Le principe consiste à réduire progressivement un intervalle de telle sorte que cet intervalle converge vers . N’importe quelle valeur dans cet intervalle est considérée comme un valable.
De manière intuitive, l’intervalle va commencer à , puis à chaque étape, on teste la valeur au milieu de cet intervalle. A chacune de ces étapes, soit on augmente la borne inférieure , soit on diminue la borne supérieure .
Par exemple, pour :
- On commence sur l’intervalle et on teste .
- L’intervalle devient et on teste donc .
- L’intervalle devient et on teste donc .
- L’intervalle devient et on teste donc .
- L’intervalle devient et on teste donc .
- L’intervalle devient et on teste donc .
- L’intervalle devient et on teste donc .
- L’intervalle devient et on teste donc .
- L’intervalle devient et on teste donc .
- L’intervalle devient et on teste donc .
- L’intervalle devient et on teste donc .
- Or , donc si , alors on a notre résultat.
Le nombre est obtenu via la fonction input
et le résultat est affiché dans la sortie standard.
L’algorithme suit les étapes suivantes :
- On lit la valeur rétournée par
input
. - On initialise à
0.01
. - On initialise à
0
. - On initialise à .
- On initialise à : on prend le milieu de l’intervalle.
- Dans une boucle :
- Si , alors la boucle s’arrête et on affiche le résultat .
- Sinon :
- Si , alors la borne prend la valeur . On est donc dans l’intervalle .
- Sinon, la borne prend la valeur . On est donc dans l’intervalle .
- On met à jour en calculant à nouveau : on prend le milieu du nouvel intervalle réduit.
Exercice 3 - Comparaison des approches
Selon vous, quelle approche de calcul de racine carrée fonctionne le mieux entre :
- une énumération dans un espace de solutions,
- l’utilisation de la dichotomie.
Pourquoi ? Veuillez justifier votre réponse avec des exemples.
Exercice 4 - Nombre négatif
Que se passe-t-il si l’utilisateur rentre ?
Que faut-il faire pour éviter cela ?
Exercice 5 - Calcul d’un logarithme
Ecrivez un script qui calcule un logarithme en utilisant la dichotomie.
Pour rappel, un logarithme en base 2 est tel que . Il s’agit donc, algorithmiquement parlant, d’un problème similaire à celui du calcul d’une racine carrée (pour lequel on avait ).
Par exemple, pour :
- On commence sur l’intervalle et on teste .
- L’intervalle devient et on teste donc .
- L’intervalle devient et on teste donc .
- Bingo, et on a trouvé le résultat exact.
Exercice 6 - Accélération du calcul de logarithme
Dans l’exercice précédent, nous avons utilisé l’intervalle de départ pour commencer la dichotomie. En pratique, il est possible de trouver très rapidement un intervalle de recherche beaucoup plus petit. Plus l’intervalle est petit, plus on diminue le nombre d’itérations nécessaires pour trouver un résultat, et plus l’exécution est rapide.
Intuitivement, la raison pour laquelle on peut trouver un meilleur intervalle de départ est la vitesse à laquelle la fonction puissance évolue :
0 | 1 |
1 | 2 |
2 | 4 |
3 | 8 |
4 | 16 |
5 | 32 |
6 | 64 |
7 | 128 |
8 | 256 |
9 | 512 |
10 | 1024 |
11 | 2048 |
12 | 4096 |
13 | 8192 |
14 | 16384 |
15 | 32768 |
16 | 65536 |
17 | 131072 |
18 | 262144 |
19 | 524288 |
20 | 1048576 |
On peut donc commencer par rechercher le plus grand nombre entier tel que .
On pourra ainsi commencer la dichotomie avec l’intervalle à la place de l’intervalle .
Par exemple, si on recherche pour , on peut voir dans le tableau ci-dessus que .
On pourra donc commencer la dichotomie avec l’intervalle à la place de l’intervalle .
Cette technique porte le nom d’approximations successives : on trouve d’abord l’intervalle puis on recherche la valeur par dichotomie, soit environ .
Réécrivez votre script de calcul de logarithme pour y intégrer l’optimisation initiale sur les bornes.