Chapitre 8 : algorithmes et arithm´etique
1 Autour de la division euclidienne
1.1 Apprentissage de l’analyse d’un algorithme : division euclidienne
a) Une remarque vue depuis le chap. 2, mais revue notamment lors du C.R. du
T.P. 6 sur la dichotomie : une des difficult´es de lecture d’un algorithme en informatique
par rapport aux math´ematiques est qu’au cours du d´eroulement d’un algorithme, une variable
peut ˆetre r´eaffect´ee et prendre successivement diff´erentes valeurs. En info., on peut penser `a
la variable comme `a un contenant et `a la valeur comme un contenu.
Cette difficult´e est aussi un avantage en terme de concision... quand on a bien compris...
comme on esp`ere le montrer ci-dessous.
b) Un algorithme pour obtenir le reste de la division euclidienne On se donne deux
entiers aet bavec b>0. Le r´esultat de la division euclidienne est le couple (q, r)tel que
a=bq +ret 0 r<b. Ici, on se limite d’abord `a la recherche du reste : pour cela on va utiliser
seulement deux variables informatiques aet b. Au d´epart dans aet b, il y a les valeurs aet
bpour lesquelles on veut calculer la division euclidienne, mais l’algorithme modifie la valeur
de la variable informatique aet on va montrer qu’`a la fin, dans ail y a le reste rque l’on
cherche. Voici l’algo. ´ecrit en Python o`u les valeurs de aet bseront donc rentr´ees comme
arguments d’une fonction appel´ee reste,volontairement non document´ee :
def reste(a,b):
while (a<0) or (a>=b):
if a<0:
a=a+b
if a>=b:
a=a-b
return a
Comment juger de la validit´e de cet algorithme ? Deux probl`emes bien distincts :
terminaison : on doit ˆetre sˆur que l’algorithme s’arrˆete au bout d’un nombre fini d’´etapes,
correction de l’algo. : on doit ˆetre sˆur que l’algorithme fait ce qu’on veut, donc ici que la
valeur renvoy´ee est bien celle du reste.
c) Le probl`eme de la terminaison :
Pour ´etudier l’algorithme on note a0=a, et akla valeur de la variable informatique aapr`es
la k-i`eme ´etape.
(M1) ici : on se place dans chacun des deux cas des if et on fait une analyse semblable `a
celle de la d´em. math´ematique.
Si a0=ab, alors a1=a0bet si on prend kle maximum des entiers tels que a0kb b
alors a0(k+1)b<bet a0(k+1)b0 (idem cours de maths). Donc l’algorithme s’arrˆete
apr`es la (k+1)-i`eme ´etape.
Si a0<0, alors a1=a0+bet si on prend kle maximum des entiers les a0+kb <0, on sait
que a0+(k+1)b0 et a0+(k+1)b<b(solution du cas laiss´e en exercice dans le cours de
maths).
(M2) avec un compteur qui diminue strictement :
Souvent on montre qu’un algorithme s’arrˆete en montrant qu’un certain nombre diminue
strictement `a chaque test de la boucle while. Souvent ce nombre est un entier naturel et
une suite d’entiers naturel ne peut pas d´ecroˆıtre strictement ind´efiniment !
Ici par exemple : on peut voir qu’apr`es chaque ´etape de l’algorithme la distance entre aet le
centre de l’intervalle [0, b]diminue strictement. Cette distance vaut abs(a-b/2) pour ´eviter
la fraction on peut consid´erer le double : abs(2a-b).
1
d) Le probl`eme de la correction :
Pour v´erifier la correction d’un algorithme, on exhibe souvent des invariants c’est-`a-dire des
objets qui ne changent pas pendant toute l’ex´ecution de l’algorithme.
Sur notre exemple : la correction se voit directement sur le raisonnement math´ematique
fait au b) et la recherche d’un invariant n’est pas si ´evidente... elle le devient si on regarde
l’algorithme plus complet qui donne (q, r)comme on va le faire maintenant.
e) L’algorithme complet de division euclidienne, et l’invariant de boucle
On se donne toujours des valeurs initiales (a, b). On pourrait n’utiliser que trois variables
informatiques a,b,q pour d´efinir la fonction Python suivante, n´eanmoins, pour plus de
lisibilit´e, on va cr´eer une quatri`eme variable r
def quo_reste(a,b):
"""renvoie le quotient et le reste de la div. eucl. de a par b"""
q=0
r=a # on aurait pu travailler avec a directement
while (r<0) or (r>=b):
if r<0:
r=r+b
q=q-1
if r>=b:
r=r-b
q=q+1
return q,r
Comme dans l’algo. pr´ec´edent, la var. bn’est pas modifi´ee, et garde toujours la valeur initiale
b,anon plus, alors que rprend comme valeur finale la valeur du reste comme on l’ a montr´e
plus haut. La variable locale qest initialis´ee `a 0 et `a la fin la fonction retourne la valeur finale
de qdont on va montrer que c’est la valeur qdu quotient de la division euclidienne de apar
b.
Ici la valeur de bq+r est un invariant de la boucle while
En effet : `a chaque ´etape on transforme bq+r en b(q-1)+(r+b) ou bien en b(q+1)+(r-b).
Quel inerˆet d’un tel invariant ? A l’initialisation l’´egalit´e bq+r==a est vraie avec les
valeurs : b×0+a=a. Donc `a l’arrˆet de l’algorithme, comme aet bn’ont pas chang´e de valeur
et comme on a d´ej`a vu qu’`a la fin de l’algo. rcontenait bien la valeur voulue pour le reste
de la div. euclidienne, la variable qcontient bien la valeur qtelle que a=bq +r.
1.2 L’algorithme d’Euclide pour le p.g.c.d.
a) Description math´ematique (donn´ee dans le cours de maths, on change l´eg`erement l’in-
dexation pour plus de commodit´e) : on se donne deux nombres (a, b)et on d´efinit une suite
finie strictement d´ecroissante d’entiers naturels (rk)k0,Npar r0=a,r1=bet pour tout
k1, tant que rk0, on d´efinit rk+1comme le reste de la division euclidienne de rk1par
rk.
La terminaison de l’algorithme est claire : la suite (rk)est une suite d’entiers naturels
strictement d´ecroissante jusqu’`a 0.
b) Algorithme informatique :
Maths : La suite (rk)est une suite r´ec. d’ordre 2 : rk+1est d´efini `a partir de rket rk1.
Traduction en info. : on a besoin d’une boucle qui modifie deux variables.
En Python en utilisant l’op´erateur %pour le reste de la div. eucl. :
2
def Euclide(a,b):
b=abs(b)# pour se ramener `a un b positif, ce qui ne change pas le pgcd
while b>0:
a,b=b,a%b
return a
Remarque : Dans un langage qui ne permet pas l’affectation en couple, on aura besoin d’une
variable locale tampon pour faire l’´echange.
c) La correction de l’algorithme : pourquoi l’algo. renvoie-t-il pgcd(a,b) ?
La justification a ´et´e donn´ee en cours de maths, et en fait, sans le dire, on a introduit un :
Invariant de boucle : `a chaque ´etape de la boucle le pgcd(a,b) est inchang´e.
Au d´epart il vaut pgcd(a, b)et `a la fin, en notation maths, il vaut pgcd(rN1, rN)avec rN=0
donc rN1.
Rappel : pour tout entier α, pgcd(α, 0)=α. Dans le cours de maths, ceci est donn´e par la
d´ef. du pgcd. avec des sous-groupes αZ+0Z=αZ.
1.3 La version soustractive de l’algorithme d’Euclide
Consid´erons l’algorithme impl´emene dans la fonction Python suivante :
def EuclideS(a,b):
"""calcul du pgcd par la m´ethode des soustractions successives"""
a=abs(a)
b=abs(b)
while (a!=0) and (b!=0):
if a<=b:
b=b-a
if b<a:
a=a-b
if a==0:
return b
if b==0:
return a
Analysons cet algorithme pour le comprendre du point de vue de la terminaison et de la
correction. On entre dans la fonctions des valeurs aet bpour les variables aet b.
a) Terminaison : La fonction prend en entr´ee des nombres suppos´es entiers, mais se ram`ene
tout de suite `a des nombre positifs. Notons (ak)et (bk)la suite des valeurs prises par les
variables informatiques aet bau fil de l’algorithme. A chaque ´etape de l’algorithme, tant que
min(ak, bk)0, on a : ak+1+bk+1=(ak+bk)min(ak, bk). Ainsi 0 ak+1+bk+1<ak+bk.
La suite (ak+bk)est bien une suite d’entiers naturels strictement d´ecroissante tant que la
boucle while se r´ep`ete. Donc la boucle while s’arrˆete.
b) Correction : pourquoi l’algorithme est-il correct, c’est-`a-dire pourquoi fait-il ce qui est
annonc´e dans la documentation ? Comme pr´ec´edemment, on exhibe un invariant de boucle.
Ici encore la valeur de pgcd(a,b) est un invariant de la boucle.
En effet, pour tout (u, v)Z2pgcd(u, v)=pgcd(uv, v)=pgcd(u, v u).
Or au d´epart de l’algorithme pgcd(a,b) vaut pgcd(a, b)et `a la fin de la l’algo l’une des deux
variables vaut 0 et par exemple si b=0, pgcd(a,0)=a donc `a la fin de l’algo. la variable a
contient le pgcd cherch´e.
3
1.4 L’algorithme d’Euclide ´etendu : obtention d’une relation de B´ezout
On se donne encore (a, b)(N)2.
a) On a vu en cours comment obtenir des coefficients d’une identit´e au +bv =do`u d=ab, en
remontant les ´egalit´es de l’algorithme d’Euclide. L’algorithme suivant permet simultan´ement
de calculer le pgcd d=abet un couple (u, v)tel que au +bv =d.
b) Math´ematiquement : On d´efinit des suites qui vont toutes ˆetre finies (rk),(qk),(uk)et
(vk)r´ecurrentes d’ordre deux, (sauf qk) comme suit :
Initialisation (double sauf pour qk) :
r0=a, q0=0, u0=1, v0=0,
r1=b, u1=0, v1=1.
Formule de r´ecurrence : pour tout k1, tant que rk0
i) (qk, rk+1)est le couple quotient-reste de la division euclidienne de rk1par rk,
ii) uk+1=uk1ukqk, et vk+1=vk1vkqk.
c) Terminaison de l’algorithme : L’algorithme pr´ec´edent contient l’algo. d’Euclide du
1.2 et a la mˆeme condition d’arrˆet donc il s’arrˆete.
d) Correction : Puisque pour les (qk)et (rk)on a la mˆeme d´ef. qu’au 1.2 on sait qu’`a l’arrˆet
de l’algorithme pour rN=0, rN1=ab. Examinons les (uk, vk):
Propri´et´e : Pour chaque k,auk+bvk=rk.
D´emonstration : notons Pkauk+bvk=rk. Preuve par r´ecurrence double :
Par l’initialisation au b) P0et P1sont vraies.
H.R. Supposons que pour un k1, Pket Pk1sont vraies.
Alors auk+1+bvk+1=a(uk1ukqk)+b(vk1vkqk)=(auk1+bvk1)qk(auk+bvk).
Donc par l’H.R., auk+1+bvk+1=rk1qkrket rk1qkrk=rk+1par d´ef. de rk+1. Ceci prouve
Pk+1. La r´ec. est ´etablie.
e) Algorithme informatique et impl´ementation en Python : cf. T.P. 8
1.5 Troisi`eme facteur d’analyse d’un algorithme : le coˆut
Une fois qu’on a ´etudi´e la terminaison et la correction d’un algorithme, on peut aussi ´etudier
son coˆut i.e. en combien d’´etapes il se termine et le nombre d’op´erations ´el´ementaires qu’il n´ecessite.
1.5.1 Premi`ere approche pour l’algorithme d’Euclide
Ex. 4 pl. 16 : On consid`ere deux entiers (a, b)N2, avec a>b, on note a=bq +rla division
euclidienne de apar b(´etape 0 de l’algo. d’Euclide). On note r0=a,r1=bet pour tout k1, tant
que rk0, on note rk+1le reste de la division euclidienne de rk1par rk. On note ici (ce qui est
diff´erent du cours), rN=rN+1qN+1+rN+2avec rN+2=0 la derni`ere ´etape de l’algorithme d’Euclide,
de sorte que cet algorithme a N+1 ´etapes.
a) Montrer que br 1
2ab et que pour tout k,rk+1rk1
2rkrk1.
Autrement dit, le produit “dividende-diviseur” est au moins divis´e par 2`a chaque ´etape de
l’algo. d’Euclide
b) En d´eduire que si on note N+1 le nombre d’´etapes de l’algorithme d’Euclide appliqu´e `a a
et balors Nest major´e par log2(a)+log2(b).
4
Solution de l’exercice du 1.5.1
a) Remarque : Au brouillon : que veut-on montrer ? Que br 1
2ab i.e. que ab 2br i.e. que
a2rbon, au travail !
Par d´ef. de la division euclidienne, on a a=bq +ravec r<b.
En outre, comme a>b, on a q1 donc b+ra. Ainsi 2ra.
Donb 2br ab comme demand´e. C’est ´evidemment la mˆeme chose `a chaque ´etape.
b)Remarque : Au brouillon : que veut-on montrer ? Si N+1est le nombre d’´etapes de l’al-
gorithme, on veut montrer que Nlog2(a)+log2(b)i.e. que 2Nab ah cela ressemble plus au
a)...
Notons Nle nombre d’´etapes de l’algorithme d’Euclide. Avec la notation (rk)introduite ci-
dessus pour les restes successifs de l’algo. d’Euclide, et en notant r=r0, `a l’´etape 2, on a r1r0ab
4,
et `a l’´etape k, on a rk1rk2ab
2k, `a la derni`ere ´etape, on a rN1rN2ab
2Navec rN=0.
La derni`ere division euclidienne s’´ecrit rN2=qNrN1+0 avec rN2et rN1des entiers positifs
non nuls.
Il est tr`es utile de penser qu’un entier positif non nul m v´erifie m1
Donc 1 rN1rN2ab
2N.
Donc ab 2Ndonc Nlog2(ab)et la conclusion.
Remarque Ainsi si on veut calculer le pgcd de deux nombres `a 300 chiffres, le nombre de pas
est inf´erieur `a 2 log2(10300)=600 log2(10)<2000.
Remarquons aussi que log2(a)est moins que le nombre de chiffres de adans l’´ecriture en base
2, donc que l’algo. d’Euclide ne prend pas plus d’it´erations que le nombre de bits n´ecessaires pour
´ecrire aet ben base deux.
5
1 / 5 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !