1
Baccalauréat blanc ISN- mars 2013
Le crible d’Ératosthène
Documents et calculatrice interdits
Le texte à lire est long, mais vous verrez qu’il y a peu de questions. Je ne
voulais pas vous donner un algorithme sans explications.
Lisez le texte, mais sachez que tout est ensuite résumé, dans les parties
encadrées.
Comment calculer le plus rapidement possible tous les nombres premiers jusqu’à un
milliard ?
Un nombre premier est un nombre entier naturel ayant la caractéristique de n’être divisible sans reste
par aucun autre entier naturel que 1 et lui-même. Les nombres premiers sont répartis irrégulièrement
parmi tous les nombres entiers naturels. C’est pourquoi ils fascinent les mathématiciens depuis des milliers
d’années. ( 4 n’est pas premier car divisible par 2 mais 3 est premier car n’est divisible que par 1 et par lui-
même..)
La suite de tous les nombres premiers compris entre 1 et n commence de la façon suivante :
2 3 5 7 11 13 17 19 23 29 31 37 41 ...
De nombreuses problématiques dans lesquelles les nombres premiers jouent un rôle ont émergé au fil
du temps. Toutes n’ont pas encore été résolues.
Aujourd’hui, les nombres premiers ne sont plus seulement un défi pour les mathématiciens, mais ont
une valeur pratique. Ainsi, les nombres premiers à 100 chiffres jouent un rôle central dans le cryptage
électronique de données (cryptage RSA).
De l’idée à la réalisation
D’après les connaissances actuelles, le premier à avoir présenté un algorithme pour calculer les tableaux
de nombres premiers était un savant grec de haut rang dans l’ancienne Alexandrie, Eratosthène de Cyrène
(env. 276-194 avant JC).
Nous allons donc étudier la rapidité de cet algorithme dans la pratique pour calculer un grand tableau
de nombres premiers. Prenons comme limite un milliard, soit n = 109.
Une idée simple
Selon la définition des nombres premiers, pour chaque nombre m qui n’est pas un nombre premier, il
existe deux entiers i et k (différents de 1 et m) tels que i . k = m. Nous pouvons utiliser cette égalité pour
formuler un algorithme très simple afin de construire un tableau de nombres premiers :
Tableau de nombres premiers (méthode de base)
Écrire tous les entiers de 2 jusqu'à n dans un tableau
Calculer tous les produits i . k où les entiers i et k sont compris entre 2 et n
Barrer tous les résultats figurant dans le tableau
On constate immédiatement que cette simple règle fait bien ce qui est attendu : tous les nombres qui
sont encore dans le tableau à la fin ne sont pas le résultat d’un des produits calculés. Ils ne peuvent donc
pas être écrits comme un tel produit et sont donc des nombres premiers.
À quelle vitesse se fait le calcul ?
2
Pour étudier plus précisément le déroulement de l’algorithme et de ses différentes étapes, écrivons de
façon plus formelle les instructions contenues dans l’idée de base et attribuons un numéro à chaque
étape :
Tableau de nombres premiers_méthode de base
1 Écrire tous les entiers de 2 jusqu'à n dans un tableau
2 Pour chaque entier i de 2 jusqu’à n faire :
3 Pour chaque entier k de 2 jusqu’à n faire :
4 Barrer le nombre i . k du tableau
QUESTIONS :
Vous trouverez en annexe, le code en Java-processing qui implémente cet algorithme.
1) Compléter sur la feuille d’annexe la fonction intialiserTableau
2) Justifier la condition (i*k<estPremier.length) sur votre copie
3) Compléter sur la feuille d’annexe la fonction afficherTableau
Cet algorithme peut être programmé très facilement sur un ordinateur et nous pouvons constater le
temps nécessaire à son exécution. Sur un PC de 3,2 GHz fonctionnant sous Linux, voici les temps de calcul :
n
103
104
105
106
Temps
0,00 s
0,20 s
19,4 s
1 943,4 s
On observe qu’une augmentation de n d’un facteur 10 prolonge le temps de calcul d’un facteur
d’environ 100. Ceci est prévisible, car i tout comme k sont pris dans une plage dix fois plus grande. Donc
100 fois plus de produits i . k sont calculés.
De là, nous déduisons que pour arriver à n = 109, nous devons augmenter le temps nécessaire pour n = 106
d’un facteur (109 / 106)2 = 106. Nous aurions donc besoin de 1943 . 106 secondes soit 61 ans et 7 mois. C’est
naturellement impossible dans la pratique.
Quelles étapes de l’algorithme sont gourmandes en temps ?
L’algorithme génère tous les produits i . k dans une certaine plage :
Toutefois, chaque résultat est utilisé une seule fois. Il est ensuite suppridu tableau et l’algorithme
n’aurait plus jamais besoin de le recalculer. À quel moment travaille-t-il trop ? Notamment où les valeurs
de i et k sont interverties, par exemple i = 3, k = 5 et plus tard i = 5, k = 3. Dans les deux cas, le résultat du
produit est le même, car la multiplication est commutative : on obtient toujours i . k = k . i. C’est pourquoi,
pour éviter ces doublons, nous pouvons préciser k i.
3
Cette idée épargne d’emblée la moitié du travail ! Toutefois, 30 ans et 10 mois restent encore bien trop
longs pour obtenir notre tableau. Où pouvons-nous réduire la quantité de travail à réaliser ? Précisément
dans l’étape 4 où il ne se passe rien quand i . k > n. Le tableau contient seulement des nombres jusqu’à n,
les nombres au-delà de n ne sont pas pris en compte.
De ce fait, nous avons besoin de la boucle k (ligne 3) seulement pour les valeurs telles que i . k n. Cette
condition même nous donne les valeurs de k : k n / i.
Nous pouvons simultanément délimiter la plage de valeurs pour i. À partir des deux restrictions
i k n / i, nous obtenons i² n, donc i n. Pour i supérieur, le domaine k est vide.
Voici comment se présente le nouvel algorithme :
Tableau de nombres premiers_méthode améliorée
1 Ecrire tous les entiers de 2 jusqu'à n dans un tableau
2 Pour chaque entier i de 2 jusqu’à n faire :
3 Pour chaque entier k de i jusqu’à (n / i )faire :
4 Barrer le nombre i . k du tableau
QUESTIONS :
4) Modifier en vert sur la feuille d’annexe le programme en java-processing de l’annexe.
Donnée : la racine carré, se note sqrt. Exemple racine carré de 5, se note sqrt(5).
Quelle vitesse atteignons-nous à présent ? Voici les nouveaux temps de calcul :
104
106
107
109
Temps
0,00 s
0,01 s
2,3 s
452,9 s
L’effet bénéfique se fait déjà sentir, l’objectif 109 n’est plus hors d’atteinte : il est seulement à sept
minutes et demie. Laissons l’ordinateur travailler et profitons de ce moment pour essayer d’encore
améliorer l’algorithme !
Avons-nous besoin de toutes les valeurs de i ?
4
Observons ce qui se passe exactement dans la boucle i (ligne 2) : i reste le même pendant que k
parcourt sa boucle (ligne 3). Ainsi, le produit i . k prend successivement les valeurs
i², i(i+1), i(i+2)...
Au moment où la boucle k est terminée, plus aucun multiple de i ne figure dans le tableau. Mais il en va
de même pour tous les multiples des nombres inférieurs à i, puisqu’ils ont déjà été supprimés de la même
façon.
Que se passe-t-il si i n’est pas un nombre premier ? Prenons par exemple i = 4. Le produit i . k parcourt les
valeurs 16, 20, 24... On constate que ces nombres sont tous aussi des multiples de 2, étant donné que 4 est
lui-même un multiple de 2. De ce fait, aucun calcul n’est nécessaire pour i = 4. Et il en va de même pour
tous les autres nombres pairs i > 4.
Prenons l’exemple i = 9. Le produit i . k parcourt seulement des multiples de 9. En tant que multiples de 3,
ils ont déjà été considérés, il est donc inutile de les parcourir à nouveau. Le cas de figure est le même avec
tous les nombres qui ne sont pas premiers, car ils ont un diviseur premier plus petit qu’eux, qui
représentait avant eux une valeur de i. Nous avons donc besoin de parcourir la boucle k seulement lorsque
i est un nombre premier.
Comment savoir si i est un nombre premier ou non ? Le tableau lui-même pourrait nous l’indiquer – si il
était déjà termi. C’est seulement après avoir terminé l’exécution de l’algorithme que nous pouvons être
certains qu’il reste seulement des nombres premiers dans le tableau. Jusqu’ici, vous êtes d’accord ?
Eh bien, oui et non. En général, oui, car sinon nous pourrions abréger l’algorithme. Or cela n’est pas
toujours possible. Prenons par exemple n = 100 : le nombre non premier 91 doit être à un moment ou à un
autre supprimé du tableau. Il est produit juste avant la fin, il correspond en effet à i = 7, k = 13.
Dans notre cas précis, non, car nous ne cherchons pas à trouver n’importe quel nombre premier, mais à
déterminer si un nombre en particulier, le nombre i, est premier. Et ce, pas à n’importe quel moment, mais
plutôt au début de la boucle k pour la valeur i. Ici, le tableau nous donne une bonne information !
Pourquoi ?
Nous avions observé plus haut que pour chaque valeur de i, toutes les valeurs i . k supprimées sont telles
que i . k i². Autrement dit : dans la suite 2, ..., i² - 1, rien n’est modifié. Étant donné que i ne fait
qu’augmenter dans le temps, cette suite augmente aussi et comprend toutes les suites formées avant elle.
Sur le schéma suivant, ces suites sont encadrées :
Comme plus aucun changement n’apparaît dans ces suites jusqu’à la fin de l’algorithme, elles doivent
être déjà correctes avant le passage de la boucle k pour le i que l’on considère. Le tableau est pour ainsi
dire prêt en quatre étapes. Ce qui est à gauche est la valeur i dont nous souhaitons vérifier la qualité de
nombre premier. On constate qu’elle est toujours dans une zone encadrée. Pour décider si i est un nombre
5
premier, nous pouvons donc vérifier s’il figure dans le tableau courant.
Nous pouvons affiner la boucle i dans l’algorithme comme ci-dessous :
Tableau de nombres premiers_crible d’Ératosthène
1 Ecrire tous les entiers de 2 jusqu'à n dans un tableau
2 Pour chaque entier i de 2 jusqu’à n qui n’est pas barré dans le tableau faire :
3 Pour chaque entier k de i jusqu’à (n / i) faire :
4 Barrer le nombre i . k de le tableau
QUESTIONS
5) Que signifie « barrer un nombre » dans le programme en Java-Processing ? Comment reconnaitre un
nombre « qui n’est pas barré » dans le programme en Java-Processing ?
6) Modifier le programme pour réaliser l’algorithme ci-dessus. Recopier la partie modifiée sur votre
copie.
C’est ce procédé qui avait été présenté par Ératosthène et qui s’appelle le crible d’Ératosthène d’après
son inventeur. C’est un crible, car il ne construit pas méthodiquement les nombres premiers, mais retire au
contraire tous les nombres qui ne sont pas premiers.
Voici les temps de calcul pour cet algorithme :
n
106
107
108
109
Temps
0,02 s
0,43 s
5,4 s
66,5 s
Pour n=109, ça fait encore une bonne minute !
Peut-on faire encore plus rapide ?
Avec un argument similaire à celui pour les valeurs de i, nous pouvons également restreindre les valeurs
de la boucle k : nous avons besoin de regarder seulement celles que l’on trouve dans le tableau. Si k ne s’y
trouve plus, alors k est supprimé en tant que nombre non premier et a un diviseur premier p < k. Au
passage de la boucle i avec i = p, tous les multiples de p sont supprimés, en particulier k et ses multiples. Il
n’y a donc plus rien à faire à cet endroit.
Il serait logique de compléter l’algorithme comme ci-dessous :
3 Pour chaque nombre k := i... n / i dans le tableau faire :
4 ...
Attention ! Cette formule n’est pas parfaite. Si on exécute l’algorithme de cette manière, il génère le
tableau suivant :
2 3 5 7 8 11 12 13 17 19 20 23 27 28 29 31 32 37 41 43
44 ...
Qu’est-ce qui ne va pas ? Regardons plus précisément les premières étapes de l’algorithme. Voici le
résultat après initialisation du tableau avec tous les nombres jusqu’à n (ligne 1) :
2 3 4 5 6 7 8 9 10 11 ...
Tout d’abord, on pose i = 2, puis k = 2. Le nombre 2 est dans le tableau, donc on supprime i . k = 4 :
2 3 - 5 6 7 8 9 10 11 ...
Ensuite, k = 3. Le nombre 3 est lui aussi dans le tableau, donc on supprime i . k = 6 :
2 3 - 5 - 7 8 9 10 11 ...
Et maintenant : k = 4 ne figure plus dans le tableau, car il a été supprimé en premier. Rien n’est donc fait
pour k = 4 à cause de la nouvelle restriction et l’algorithme poursuit avec k = 5 :
2 3 - 5 - 7 8 9 - 11 ...
2 . 4 = 8 reste donc par erreur dans le tableau. Le problème est que k supprime constamment des
nombres plus grands que lui i . k > k lors du passage de la boucle, puis lui-même augmente. À un moment
donné, k prend la valeur d’un ancien produit i . k et le procédé a des répercussions néfastes sur lui-même :
1 / 8 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 !