Supplément de révisions - K. REINE
Correction de l’examen - SESSION 2024
Cette correction peut être erronée car faite à partir de mes connaissances, si vous trouvez des erreurs, n’hésitez pas !
1) Algorithmique de codage binaire
Dans cette section, on s’intéresse au codage binaire d’un entier. Pour cela on propose l’algorithme ci-dessous. Cet algorithme utilise le type vecteurBooleen. On suppose que si v est un vecteurBooleen, l(v) retourne sa longueur (nombre de coordonnées) et v[i] permet d’accéder (de modifier, ou même de créer) sa i-ème coordonnée, avec . vecteurVide() crée un vecteur booléen vide.
Algorithme
Entree :
k un entier
Sortie :
un vecteurBooleen
variables :
n,i deux entiers entiers
v un vecteurBooleen
debut A
n <- k; i <- 0; v <- vecteurVide()
TANT QUE ( n >= 1) FAIRE
SI (n MOD 2 = 0) ALORS
v[i] <- 0
SINON v[i] <- 1
FIN SI
n <- n DIV 2; i++
FIN TANT QUE
RETOURNER v
fin A
- Montrer que l’algorithme se termine. Pour cela vous utiliserez un variant. Lequel ?
Pour commencer, on peut récapituler ce que fait l’algorithme .
INITIALISATION
n = k
i = 0
v = []
BOUCLE TANT QUE n >= 1
FIN lorsque n<1
SI n pair : v[i]=0
SI n impair : v[i]=0
n = quotient divEuclidienne n/2
i + 1
FIN BOUCLE
Renvoyer le vecteur créé
L’algorithme admet une boucle TANT QUE, c’est sur elle que nous allons “zoomer” pour déterminer un variant de boucle.
Rappel
Un variant noté est une valeur entière qui décroit strictement à chaque itération d’un algorithme.
On remarque dans la boucle qu’à chaque itérations, on divisera la variable n par 2. Ainsi, cela revient à dire que dans tous les cas la valeur de n à l’itération i+1 sera toujours plus petite que la valeur de n à l’itération i. D’où n décroit à chaque itérations, alors il y aura forcément un moment où n<1 alors la boucle while s’arrêtera et l’algorithme pourra se terminer en renvoyant le vecteurBooleen créé.
En conclusion, on définit un variant qui permet de montrer qu’à chaque itération il diminue jusqu’à forcément devenir plus petit que , dans ce cas, après un certain nombre d’itérations, la boucle while vas se stopper et l’algorithme se terminera en renvoyant le vecteur v.
- L’objectif de l’algorithme c’est de retourner un vecteur contenant les chiffres de l’entrée écrite en binaire. Par définition si
west ce vecteur, on doit avoir :
On vas montrer que le vecteur v résultat de l’algorithme vérifie bien cette égalité. Pour cela, on va montrer par récurrence sur l’existence d’un invariant.
Notons la valeur de au début de la itération.
Soit alors
Montrer que la fonction est un invariant, c’est à dire qu’elle est constante pour tout lors de l’algorithme. Votre preuve sera par récurrence sur .
Soit la itération de l’algorithme. Alors :
-
INITIALISATION Pour alors on a : On se trouve avant la boucle
while, à ce moment là, au début de tout l’algorithme, avant d’entrer dans la boucle, on a : , , ,Alors on a ainsi l’initialisation est vérifiée et montre que est un invariant.
-
HÉRÉDITÉ On suppose que est un invariant pour un fixé, en gros on suppose que est un variant pour toutes les itérations . On chercher à montrer que est aussi un invariant. Soit l’itération alors on sait que :
$$ v[i]=n_i MOD 2 $$ $$ n_{i+1} = n_i DIV 2 $$Ainsi on se retrouve avec :
Je peux utiliser les propriétés des divisions euclidiennes. Soit alors
où :
- est le quotient
- le reste Dans notre cas :
- On cherche la valeur de donc si on repart de la formule de base de la division euclidienne de deux entiers on a :
D’où :
Ainsi notre invariant reste valide avant pendant et après la boucle while.
Ainsi est un invariant de l’algorithme et on a :
$$
I(l(w))=2^{l(w)}\times n_{l(w)}+\underset{j=0}{\overset{l(w)-1}{\sum}}v[j]2^j=k \quad et \quad k=\underset{j=0}{\overset{l(w)-1}{\sum}}w[j]2^j
$$
3) Supposons que soit une puissance de avec où est un entier positif. En déduire que le nombre d’itérations de est exactement égal à .
Puisque est une puissance de alors :
- avec positif.
On vas alors regarder ce qu’il se passe au début, au milieu et à la fin de l’algorithme à chaque itérations. À chaque itération
Regardons ce qu’il se passe pour l’algorithme lorsque l’on prend comme entrée.
- Pour
Alors, on se trouve avant la boucle, c’est là où on initialise nos variables.
Alors :
- ()
- Pour
- Pour une boucle générale
- Pour
- Pour
- Puisque devient inférieur à alors la boucle s’arrête à l’itération , ce qui montre bien que pour on fait itérations. Cela montre aussi que :
- On admettra que si , alors le nombre d’itérations de l’algorithme est égal à . En déduire le complexité de l’algorithme.
On admet que alors :
Puisque on dit que le nombre d’itérations de l’algorithme est égal à , et que est de l’ordre de alors la complexité de l’algorithme est donnée par :
Algorithme mystère
Soit l’algorithme suivant (le type VecteurBooleen est défini dans la première question)
Algorithme
Entrees :
x un entier
v un vecteurBooleen
Sortie :
un réel
debut B
R <- 1; u <- x
pour (i = 0 -> l(v)-1) faire
si v[i]=1 alors
R <- R*u
fin si
u <- u*u
fin pour
retourner R
fin B
- TESTS Appliquer l’algorithme aux entrées suivantes en donnant bien l’évolution des variables
Retu: À votre avis, que fait cet algorithme ?
Nous allons commencer par effectuer les tests un par un en détaillant les valeurs de R et de u lors de l’exécution.
-
Pour
- INIT et
- Boucle
pourElle vas de à et comme , la boucle vas de jusqu’à .- Pour l’itération alors
- Pour l’itération alors
- SORTIE de la boucle à la sortie de la boucle, on se retrouve avec et .
- SORTIE de l’algorithme L’algorithme renvoi la valeur de qui ici est ainsi :
-
Pour
- INIT et
- Boucle
pourElle vas de à , et puisque alors la boucle pour itère pour de à .- Pour l’itération alors la valeur de ne change pas
- Pour l’itération alors la valeur de ne change pas
- Pour l’itération alors
- SORTIE de la boucle En sortie de boucle, la valeur de .
- SORTIE de l’algorithme L’algorithme renvoi qui ici vaut . d’où
-
Pour
- INIT et
- Boucle
pourElle vas de à puisque donc .- Pour l’itération alors
- Pour l’itération alors reste inchangé.
- Pour l’itération alors
- SORTIE de la boucle En sortie de la boucle pour .
- SORTIE de l’algorithme
A la fin, l’algorithme renvoi la valeur de qui ici est , on note
On cherche maintenant à savoir ce que fait cet algorithme. Pour rappel le paramètre est un
vecteurBooleenqui donne le code d’un nombre en base regardons si cette aspect peut nous aider à comprendre. Pour chaque test :
-
-
-
Et là, on regarde les sorties des algorithmes et on se rend très vite compte que : Ainsi, l’algorithme permet de calculer la à la puissance où représente le nombre en base contenu dans le vecteur .
- Montrer simplement que l’algorithme se termine.
L’algorithme ne possède aucune boucle infinie (while), la seule boucle qu’il possède est une boucle for qui vas de à et puisque la taille du vecteurBooleen v est déterminé début de l’algorithme alors la boucle pour se terminera forcément après un nombre fini d’itération, pur être exact au bout de itérations. Ainsi, l’algorithme n’est pas infini, il se finira forcément et renverra une valeur pour .
- On suppose dans la suite que l’algorithme est correct. Donnez la complexité de l’algorithme en fonction de , en utilisant la notation de Landau . On supposera que l’opération de multiplication de réels est une opération élémentaire.
Si on reprends l’algorithme , on remarque que peut importe le contenu du vecteur qu’il ne contienne que des , que des ou les deux, cela ne changera rien à l’exécution de cet algorithme puisque dans tous les cas la boucle pour itérera de à . Ainsi le nombre d’itérations est donné par , l’algorithme effectuera dans tous les cas fois la boucle pour. D’où :
Algorithme de calcul d’une puissance
Soit l’algorithme ci-dessous. Algorithme
Entrees :
x un réel
k un entier
Sortie :
reel
Variable :
vecteurBooleen v
debut C
v <- A(k)
retourner B(x ,v)
fin
- Expliquer (sans prouver sa correction) pourquoi l’algorithme calcul bien . Déduire des deux sections précédentes la complexité de l’algorithme en fonction de .
L’algorithme :
- Il permet de créer un
vecteurBooleen vgrâce à l’algorithme . En fait, ici le vecteur vas contenir le codage de l’entier en binaire. - Il retourne le réel élevé à la puissance du nombre codé en base dans le vecteur et puisque l’on a défini à l’instant que contient le codage de alors l’algorithme retourne bien .
Si on récupère les deux complexités précédentes :
On sait que représente la taille du vecteur qui représente la taille de l’entrée et qui suit en fait en terme d’ordre de grandeur alors on se retrouve avec : La complexité de l’algorithme est donnée par .