Mathématiques Discrètes et Algorithmique - LMPT

publicité
Université François Rabelais de Tours
Laboratoire de Mathématiques et Physique Théorique
Mathématiques Discrètes et Algorithmique
UE 5-4 Option
Semestre 5
2. Quelques algorithmes classiques
Dans ce chapitre nous présenterons quelques algorithmes classiques, ce qui nous permettra d’une part de
nous familiariser avec le langage algorithmique (le pseudo-code) et d’autre part d’introduire des notions
essentielles à l’algorithmique.
2.1. La division euclidienne. Rappelons tout d’abord la définition de la division euclidienne.
Théorème 2.1. Soient a ∈ N et b ∈ N tels que b 6= 0. Il existe un unique couple (q, r) ∈ N2 tel que
a = qb + r
0≤r ≤b−1
où
On peut calculer le couple (q, r) avec l’algorithme suivant.
Données : a, b ∈ N, b > 0
Résultat : (q, r) tel que a = bq + r
q := 0
r := a
tant que r ≥ b faire
q := q + 1
r := r − b
fin
retourner (q, r)
Algorithme 2: Division Euclidienne
Exemple 2.2. Appliquons cet algorithme avec les
les valeurs suivantes :
test
Initialisation
1ère boucle
2ère boucle
3ère boucle
4ère boucle
valeurs (14, 3). Les variables prennent successivement
du tant que
14 ≥ 3
11 ≥ 3
8≥3
5≥3
2≥3
q
0
1
2
3
4
r
14
11
8
5
2
On a bien 14 = 4 ∗ 3 + 2.
Notation : Soient (a, b) ∈ N2 tels que b > 0. On écrira a mod b pour désigner le reste
de la division euclidienne de a par b et a ÷ b pour désigner le quotient.
On rappelle que le pgcd(a, b) est le plus grand diviseur commun de a et b. On a
Théorème 2.3. Soit (a, b) ∈ N2 − {(0, 0)}. Il existe r, s ∈ Z tels que pgcd(a, b) = ra + sb
L’algorithme pour calculer r et s de ce théorème est basée sur le résultat suivant :
Lemme 2.4. Soit a = bq + r où a, b, q, r ∈ N. On a pgcd(a, b) = pgcd(b, r)
L’algorithme le plus connu pour calculer r, s est l’algorithme d’Euclide étendu. Plutôt que de décrire
l’algorithme, donnons un exemple concret :
65 = 9 · 7 + 2
9=2·4+1
et donc pgcd(65, 9) = 1. On a
1 = 9 − (2 · 4) = 9 − 4 · (65 − 9 · 7) = 29 · 9 − 4 · 65.
1
2
Cet algorithme n’est pas très efficace car il necessite la mémorisation de toutes les étapes de calculs intermédiaires. Nous allons présenter un algorithme bien plus efficace, l’algorithme de Blankinship.
Supposons que nous voulions calculer le pgcd de 252 et 198. Pour calculer u et v on construit la matrice
suivante
!
252 1 0
M0 :=
198 0 1
puis on applique l’algorithme d’Euclide dans la première colonne tout en étendant les manipulations de
lignes au reste de la matrice. Ce sera plus clair sur un exemple :
Ancienne Matrice
!
252 1 0
M0 :=
198 0 1
!
54 1 −1
M1 :=
198 0 1
!
54 1 −1
M2 :=
36 −3 4
!
18 4 −5
M3 :=
36 −3 4
Pivot
Manipulation
198
L1 := L1 − L2
54
L2 := L2 − 3L1
36
L1 := L1 − L2
18
L2 := L2 − 2L1
Nouvelle matrice
!
54 1 −1
M1 :=
198 0 1
!
54 1 −1
M2 :=
36 −3 4
!
18 4 −5
M3 :=
36 −3 4
!
18
4
−5
M4 :=
0 −11 14
L’algorithme s’arrête lorsque la première colonne contient le pgcd. On a alors
Dans l’algorithme , on notera M :=
18 = 4 × 252 − 5 × 198
!
a u1 v1
.
b u2 v2
Données : a, b ∈ N∗
Résultat : (u, v) tel que d = au + bv
u1 := 1
v1 := 0
u2 := 0
v2 := 1
tant que a > 0 et b > 0 faire
si a ≥ b alors
q := a ÷ b
a := a − q × b
u1 := u1 − q × u2
v1 := v1 − q × v2
sinon
q := b ÷ a
b := b − q × a
u2 := u2 − q × u1
v2 := v2 − q × v1
fin
fin
si a>0 alors
pgcd := a
u := u1
v := v1
sinon
pgcd := b
u := u2
v := v2
fin
retourner (u, v)
Algorithme 3: Algorithme de Blankinship
3
Démonstration de l’algorithme : On définit les matrices suivantes :
!
!
1 λ
1 0
U (λ) =
, L(λ) =
0 1
λ 1
Soit M une matrice à deux lignes. On voit facilement que la matrice
1. U (λ)M est obtenue à partir de M en ajoutant λ-fois la deuxième ligne de M à la première ;
2. L(λ)M est obtenue à partir de M en ajoutant λ-fois la première ligne de M à la deuxième.
Dans l’algorithme de Blankinship, on multiplie sucessivement la matrice M par des matrices E1 , . . . , En
de type U (λ) ou L(λ). On pose E = En . . . E1 . Lorsque l’algorithme se termine on a
!
!
d u v
0 u′ v ′
En . . . E1 M =
ou En . . . E1 M =
0 u′ v ′
d u v
On a donc (nous n’étudierons que le premier cas, le deuxième étant similaire)
!
!
!
a
a
d u v
,E .
, I2 = E
=E
′
′
b
b
0 u v
!
u v
. En regardant le coefficient [1, 1] dans l’égalité ci-dessus, on a
Par identification on obtient E =
u′ v ′
d = au + bv.
2.2. Ecriture des nombres dans différentes bases. La manière conventionnelle d’écrire les nombres est
l’écriture décimale. On utilise les chiffres 0–9 pour représenter les puissances de 10. Par exemple lorsqu’on
écrit 34765 on veut dire
3 × 104 + 4 × 103 + 7 × 102 + 6 × 101 + 5 × 100 .
En fait, tout nombre entier positif peut jouer le rôle de base.
Théorème 2.5. Soit b ∈ N∗ . Tout nombre entier n s’écrit uniquement sous la forme
n = ak bk + ak−1 bk−1 + . . . + a1 b + a0
où ai est un entier tel que 0 ≤ ai ≤ b − 1 pour tout i = 0, . . . , k et ak 6= 0. Cette expression est appelée
l’écriture de n en base b.
Démonstration. On ne montrera que l’existence. L’idée est simple : appliquer l’algorithme de division
euclidienne. Premièrement on divise n par b
n = bq0 + a0 où 0 ≤ a0 < b.
On divise alors q0 par b :
q0 = bq1 + a1 où 0 ≤ a1 < b.
On continue
q0
q1
=
=
qk−2
qk−1
=
=
bq1
bq2
..
.
bqk−1
b.0
+ a1
+ a2
..
.
+ ak−1
+ ak
où 0 ≤ a1 < b
où 0 ≤ a2 < b
où 0 ≤ ak < b
où 0 ≤ ak+1 < b
On doit avoir qk = 0 pour un certain k ∈ N puisque
n > q0 > q1 > . . . ≥ 0.
et une suite strictement décroissante d’entier se termine par 0. Finalement, on a
n = bq0 + a0
= b(bq1 + a1 ) + a0
= b(b(bq2 + a2 ) + a1 ) + a0
= ...
= ak bk + ak−1 bk−1 + . . . + a1 b + a0
4
Exemple 2.6. Ecrivons 456 en base 9. On applique l’algorithme de la preuve :
456 =
50 =
5 =
9 · 50 +
9·5 +
9·0 +
6
5
5
et on obtient 456 = 5 · 92 + 5 · 9 + 6.
Définition 2.7. On écrit (ak , ak−1 , . . . a1 , a0 )b pour représenter l’entier n en base b :
n = ak bk + ak−1 bk−1 + . . . + a1 b + a0 .
Voici un algorithme, pour calculer l’écriture en base b d’un nombre n.
Données : n, b ∈ N, b > 1
Résultat : (ak , . . . , a1 , a0 ) tel que n = ak bk + . . . + a1 b + a0
q := n
k := 0
tant que q 6= 0 faire
ak := q mod b
q := q ÷ b
k := k + 1
fin
retourner (ak , . . . , a1 , a0 )
Algorithme 4: Ecriture en base b
Exemple 2.8. Appliquons l’algorithme à n = 201 et b = 2 :
Initialisation
boucle 1
boucle 2
boucle 3
boucle 4
boucle 5
boucle 6
boucle 7
boucle 8
q
201
100
50
25
12
6
3
1
0
k
0
1
0
0
0
0
0
0
0
Liste des ak
∅
(1)
(0, 1)
(0, 0, 1)
(1, 0, 0, 1)
(0, 1, 0, 0, 1)
(0, 0, 1, 0, 0, 1)
(1, 0, 0, 1, 0, 0, 1)
(1, 1, 0, 0, 1, 0, 0, 1)
On obtient 201 = 27 + 26 + 23 + 20 = (11001001)2.
Proposition 2.9. Soit (n, b) ∈ N avec b > 1. Le nombre de chiffres dans l’écriture de n en base b est
⌊logb (n)⌋ + 1 := ⌊
log n
⌋+1
log b
Démonstration. Montrons que tout n tel que bk−1 ≤ n < bk peut s’écrire avec k chiffre en base b. On
procède par induction sur k.
Initialisation. Si 1 ≤ n < b alors n = (n)b et n s’écrit avec 1 chiffre en base b.
Hérédité. Soit k > 1. Supposons que le résultat est vrai pour k − 1 et soit n tel que bk−1 ≤ n < bk . Soit
n−r
(q, r) ∈ N2 tel que n = bq + r avec 0 ≤ r < b. On a alors q =
et
b
n−r
bk
<
= bk−1
b
b
bk−1 − b
n−r
>
= bk−2 − 1
b
b
et comme q est un entier on obtient bk−2 ≤ q < bk−1 . L’hypothèse de récurrence implique que q s’écrit
avec k − 1 chiffres en base b i.e. (q)b = (ak−2 , . . . , a0 ) où ak−2 6= 0. Alors
(n)b = (ak−2 , . . . , a0 , r)
5
et n s’écrit avec k chiffres en base b.
On applique le logarithme à l’inégalité bk−1 ≤ n < bk . On obtient
log(bk−1 ) ≤ log n < log bk c’est à dire k − 1 ≤
log n
<k
log b
et ⌊logb (n)⌋ + 1 = k.
2.3. Exponentation modulaire rapide. En cryptographie, il est extrêmement important de pouvoir
calculer rapidement bm mod n. Ce genre d’opération est généralement effectué sur des nombres qui
contiennent 150, 200 voire 300 chiffres. Dans ce contexte il est hors de question de d’abord calculer bm
puis de réduire modulo n.
L’idée est d’utiliser l’écriture binaire de m (en base 2). Soit m = (ak−1 , . . . , a1 , a0 )2 . On a alors
k−1
bm = bak−1 ·2
. . . ba1 ·2 ba0
k
Pour calculer bm il suffit donc de calculer b, b2 , (b2 )2 , (b4 )2 . . . b2 . Lorsqu’on a ces valeurs, il suffit de mulj
tiplier entre elles les valeurs b2 qui vérifient aj = 1. On obtient ainsi bn .
Exemple 2.10. Supposons que l’on veuille calculer 311 . On a 311 = 38 · 32 · 3. On calcule successivement
32 = 9, 34 = 92 = 81, 38 = (81)2 = 6561.
Finalement on obtient 311 = 6561 · 9 · 3 = 177 147.
Dans le cas modulaire, c’est encore plus simple, on peut (et il faut) réduire modulo n à chaque étape.
Données : b, m, n ∈ N∗
Résultat : bm mod n
n = (ak−1 , . . . , a0 )2
x := 1
power := b mod n
pour i = 0 à k − 1 faire
si ai = 1 alors
x := x · power mod m
fin
power := power × power
fin
retourner x
Algorithme 5: Exponentiation modulaire
Exemple 2.11. On utilise l’algorithme pour calculer 3644 mod 645. Tout d’abord, on calcule que 645 =
(1010000100)2. On a
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
a0
a1
a2
a3
a4
a5
a6
a7
a8
a9
=0
=0
=1
=0
=0
=0
=0
=1
=0
=1
x=1
x=1
x = 81
x = 81
x = 81
x = 81
x = 81
x = 471
x = 471
x = 36
power
power
power
power
power
power
power
power
power
power
= 32 mod 645 = 9
= 92 mod 645 = 81
= 812 mod 645 = 111
= 1112 mod 645 = 66
= 662 mod 645 = 486
= 4862 mod 645 = 126
= 1262 mod 645 = 396
= 3962 mod 645 = 81
= 812 mod 645 = 111
= 1112 mod 645 = 36
2.4. Algorithme de tri : Premiers exemples. Un algorithme de tri est, en informatique ou en mathématiques, un algorithme qui permet d’organiser une collection d’objets selon un ordre déterminé. Dans ce
cours, nous allons étudier de nombreux algorithmes de tri. Nous commençons ici avec les plus simples, le
tri à bulle et le tri par insertion.
6
Le tri à bulle. C’est un algorithme de tri qui consiste à faire remonter progressivement les plus grands
éléments d’un tableau.
Données : Liste d’entiers L = (a1 , a2 , . . . , an )
Résultat : Liste d’entier triée
pour i=1 à n-1 faire
pour j=1 à n-i faire
si aj > aj+1 alors
échanger aj et aj+1
fin
fin
fin
retourner L
Algorithme 6: Tri à bulle
Exemple 2.12. Appliquons l’algorithme à la liste [3, 2, 4, 1, 5].
i=1 j=1
3
2
4
1
5
j=2
2
3
4
1
5
j=3
2
3
4
1
5
j=4
2
3
1
4
5
i=2 j=1
2
3
1
4
5
j=2
2
3
1
4
5
j=3
2
1
3
4
5
i=3 j=1
2
1
3
4
5
j=2
1
2
3
4
5
i=4 j=1
1
2
3
4
5
−→
2
3
4
1
5
−→
2
3
1
4
5
−→
2
1
3
4
5
−→
1
2
3
4
5
Le tri par insertion. C’est la méthode utilisée par les joueurs de carte. Il consiste à déplacer les éléments
de la liste “vers la gauche” jusqu’à "leurs places".
Données : Liste d’entiers L = (a1 , a2 , . . . , an )
Résultat : Liste d’entier triée
pour i=2 à n faire
j := i ;
tant que j > 1 et aj−1 > aj faire
Echanger aj et aj−1 ;
j := j − 1
fin
fin
retourner L
Algorithme 7: Tri par insertion
Exemple 2.13. Appliquons l’algorithme à la liste [3, 5, 2, 9, 7].
7
i=2
3
5
2
9
7
−→
3
5
2
9
7
i=3
3
5
2
9
7
−→
2
3
5
9
7
i=4
2
3
5
9
7
−→
2
3
5
9
7
i=5
2
3
5
9
7
−→
2
3
5
7
9
Téléchargement