Exemples de preuves d’algorithmes Algorithme de la division euclidienne Lycée Victor Hugo

publicité
Lycée Victor Hugo
MPSI-PCSI 2016-2017
Exemples de preuves d’algorithmes
Algorithme de la division euclidienne
Algorithme de division euclidienne
def d i v i s i o n _ e u c l i d i e n n e (a , b ) :
""" Division euclidienne de a par b .
a : entier positif
b : entier strictement positif
R é ponse : (q , r ) , quotient et reste .
"""
r = a
q = 0
while r >= b :
r = r-b
q = q +1
return (q , r )
• Terminaison
Notons rk la valeur de la variable r à la fin du k-ième passage dans la boucle while (donc avant un
éventuel k + 1-ième passage). On a r0 = a la valeur avant le premier passage dans la boucle.
On observe qu’en cas de (k + 1)-ième passage dans la boucle while, on a rk+1 = rk − b < rk (car b > 0).
Donc si l’algorithme ne se termine pas, la suite (rk )k∈N est une suite strictement décroissante d’entiers
positifs (rk > b pour tout k via le test d’entrée dans la boucle) ce qui n’existe pas. Donc l’algorithme
se termine bien.
• Correction
On numérote les itérations de la boucle while par i à partir de 1 et on note ri et qi le contenu des
variables r et q à la fin de la i-ième itération et r0 et q0 sont les valeurs avant une éventuelle première
entrée dans la boucle.
On définit (ce qu’on espère être un invariant de boucle) H(i) : « a = b qi + ri et ri > 0 ».
* initialisation
Avant d’entrer dans la boucle, compte-tenu des initialisations r0 = a et q0 = 0. Ainsi bq0 +r0 = 0+a = a
et r0 > 0 car a est positif d’après la documentation de la fonction, donc H(0) est vraie.
* hérédité
Supposons H(i) vraie et que l’itération numéro i + 1 a lieu.
On a donc b qi +ri = a et ri > b (condition pour avoir un i+1-ième passage dans le boucle). L’exécution
de la boucle donne ri+1 = ri −b > 0 et qi+1 = qi +1. Ainsi b qi+1 +ri+1 = b(qi +1)+(ri −b) = bqi +ri = a.
H(i + 1) est vraie.
* exploitation
À la sortie de la boucle (on suppose que l’on effectue p passages dans cette dernière), on a donc
a = b qp + rp et rp > 0 et la condition rp > b n’est pas vérifiée car on ne fait pas de p + 1-ième passage
dans la boucle while. Ainsi rp < b donc 0 6 rp < b et a = b qp + rp donc qp et rp sont donc bien
quotient et reste dans la division euclidienne de a par b. La fonction est valide.
1
Lycée Victor Hugo
MPSI-PCSI 2016-2017
Algorithme du maximum
Algorithme du calcul du maximum d’une liste non vide
def maximum ( L ) :
""" Retourne la valeur maximale des é l é ments d ’ une liste L .
L est une liste de nombres , suppos é e non vide .
"""
maxi = L [0]
for i in range (1 , len ( L ) ) :
if L [ i ] > maxi :
maxi = L [ i ]
return maxi
• Terminaison
La terminaison de cette fonction est garantie car il y a seulement une boucle for inconditionnelle, qui
n’est exécutée qu’un nombre fini de fois (ici la longueur de la liste moins 1).
• Correction
Pour prouver que le résultat final est correct on définit ce qu’on espère être un invariant de boucle :
Soit n la longueur de la liste L et H(k) l’affirmation : « À la fin de l’itération pour i = k dans la
boucle for, la valeur maxik de la variable maxi est le maximum de la liste [L[0], ..., L[k]] ».
H(0) désigne la même propriété juste avant d’entrer dans la boucle. Ainsi H(k) est définie pour k < n.
* initialisation
Avant d’entrer dans la boucle, via l’initialisation maxi0 =L[0], c’est bien le maximum de la liste à un
élément [L[0]] : H(0) est vraie.
* hérédité
Supposons H(k) vraie pour un entier k ∈ J0, n − 2K (pour qu’un passage de plus dans la boucle ait
lieu). Au début de l’itération pour i = k + 1, maxik est donc le maximum de [L[0], ..., L[k]].
Deux cas possibles se présentent :
• ou bien L[k+1] > maxik , ce qui signifie que L[k+1] est plus grand que tous les termes précédents de la liste. Dans ce cas L[k+1] est le maximum de la liste [L[0], ..., L[k+1]], et
c’est la valeur maxik+1 .
• ou bien L[k+1] 6 maxik : dans ce cas le maximum de [L[0], ..., L[k+1]] est le même que
celui de [L[0], ..., L[k]]. Comme la valeur de max n’est pas modifié, on a aussi maxik+1 =
maxik .
Dans les deux cas, H(k + 1) est vraie.
* exploitation
À la sortie de la boucle, on a i = n − 1. Or par récurrence (limitée) H(n − 1) est vraie donc la variable
codemax contient le maximum de [L[0], ..., L[n-1]] autrement dit de la liste L complète. La
fonction est valide.
2
Téléchargement