Site de Jean-Michel RICHER

Maître de Conférences en Informatique à l'Université d'Angers

Ce site est en cours de reconstruction certains liens peuvent ne pas fonctionner ou certaines images peuvent ne pas s'afficher.


Cette page fait partie du cours de polytech PeiP1 et 2 Bio

2. Mise en pratique : nombres premiers

2.1. Introduction

Dans ce TP, on s'intéresse aux nombres premiers, à leur identification et leur recherche.

On rappelle la définition d'un nombre premier : il s'agit d'un entier naturel qui possède deux diviseurs distincts : 1 et lui-même.

En conséquence le nombre 1 n'est pas premier car il ne possède qu'un seul diviseur.

La liste des premiers nombres premiers est : 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, ...

2.2. Déterminer si un nombre est premier ou non

Ecrire une fonction qui permet de déterminer si un nombre est premier ou non.

2.2.1. Première version naïve et lente

Dans un premier temps, on détermine si un nombre est premier ou non en comptant son nombre de diviseurs.

  • si un nombre $n$ ne possède que deux diviseurs alors il est premier car ses seuls diviseurs sont 1 et $n$

Cliquez sur la zone orangée pour voir apparaître les informations complémentaires liées à la fonction ci-dessous.

fonction est_premier(n)
Entrée n (entier) : nombre pour lequel on doit déterminer s'il est premier ou non
Sortie booléen, vrai si n est premier, faux sinon
Variables
locales
nbr_diviseurs (entier) : compte le nombre de diviseurs de n
Description On calcule le nombre de diviseurs de n,
s'il en existe deux alors le nombre est premier

Warning: file_get_contents(polytech/est_premier_compte_diviseurs.algo): Failed to open stream: No such file or directory in /home/jeanmichel.richer/public_html/ez_web.php on line 397
Afficher le code    polytech/est_premier_compte_diviseurs.algo
  1.  

La seule difficulté rencontrée consiste à déterminer si $i$ est un diviseur de $n$ :

  • si $i$ est un diviseur de $n$ cela signifie que $n = i × p$.
  • dans le cas contraire, cela implique que $n = i × p + r$ ; en d'autres termes, si on divise $n$ par $i$, on aura un reste $0 < r < i$.

Pour trouver le reste de la division on utilise l'opération modulo : $n\ %\ i$

L'implantation en Python est assez simple (est_premier_compte_diviseurs.py). Cliquez sur la première ligne du code pour faire apparaître l'ensemble des instructions.


Warning: file_get_contents(polytech/est_premier_compte_diviseurs.py): Failed to open stream: No such file or directory in /home/jeanmichel.richer/public_html/ez_web.php on line 397
Afficher le code    polytech/est_premier_compte_diviseurs.py
  1.  

2.2.2. Deuxième version améliorée et efficace

La version précédente n'est pas efficace pour plusieurs raisons :

  • on évalue tous les diviseurs ce qui implique beaucoup de calculs si $n$ est grand
  • il suffit de trouver un diviseur qui soit différent de 1 et de $n$ pour déterminer que $n$ n'est pas premier
  • il n'est pas nécessaire de tester tous les diviseurs pairs à partir du moment ou $n$ est divisible par 2
  • il faut limiter la recherche des diviseurs à $√(n)+1$

Prenons un exemple ($n = 37$) pour comprendre pourquoi il ne faut pas aller au-delà de $√(37)+1$

 diviseurs   quotient   reste 
 1   37   0 
 2   18   1 
 3   12   1 
 4   9   1 
 5   7   2 
 6   6   1 
 7   5   2 
 8   4   5 
 9   4   1 
 10   3   7 
 etc   etc   etc 
Recherche des diviseurs de 37

Au-delà de 7 les quotients seront nomarlement inférieurs à 7, or on a déjà testé les diviseurs de 1 à 7.

Voici l'algorithme de la fonction est_premier basée sur le calcul du nombre de divisieurs. Cliquez sur la zone orangée pour voir apparaître les informations complémentaires.

Fonction est_premier(n)
Entrée n (entier) : nombre pour lequel on doit déterminer s'il est premier ou non
Sortie booléen, vrai si n est premier, faux sinon
Description On cherche les diviseurs impairs de 3 à $√(n)+1$

Warning: file_get_contents(polytech/est_premier_amelioree.algo): Failed to open stream: No such file or directory in /home/jeanmichel.richer/public_html/ez_web.php on line 397
Afficher le code    polytech/est_premier_amelioree.algo
  1.  

L'implantation en Python pose un seul problème lié à la racine carrée car elle fait partie des calculs sur les nombres réels :

  • il est nécessaire de faire appel à la fonction sqrt (square root) de la librairie mathématique (math)
  • il faut convertir le résultat en entier

Voici le script correspondant (est_premier_amelioree.py). Cliquez sur la première ligne du code pour faire apparaître l'ensemble des instructions.


Warning: file_get_contents(polytech/est_premier_amelioree.py): Failed to open stream: No such file or directory in /home/jeanmichel.richer/public_html/ez_web.php on line 397
Afficher le code    polytech/est_premier_amelioree.py
  1.  

2.3. Trouver les cinquante premiers nombres premiers

Programme
Description Calcule les 50 premiers nombres premiers en les stockant dans une liste

Warning: file_get_contents(polytech/nombre_premier_cinquante_premiers.algo): Failed to open stream: No such file or directory in /home/jeanmichel.richer/public_html/ez_web.php on line 397
Afficher le code    polytech/nombre_premier_cinquante_premiers.algo
  1.  

La traduction en Python est la suivante (nombre_premier_cinquante_premiers_v1.py) :
Warning: file_get_contents(polytech/nombre_premier_cinquante_premiers_v1.py): Failed to open stream: No such file or directory in /home/jeanmichel.richer/public_html/ez_web.php on line 397

Afficher le code    polytech/nombre_premier_cinquante_premiers_v1.py
  1.  

On peut également utiliser une fonctionnalité de Python qui consiste à générer une liste en indiquant comment générer chaque élément : (nombre_premier_cinquante_premiers_v2.py) :
Warning: file_get_contents(polytech/nombre_premier_cinquante_premiers_v2.py): Failed to open stream: No such file or directory in /home/jeanmichel.richer/public_html/ez_web.php on line 397

Afficher le code    polytech/nombre_premier_cinquante_premiers_v2.py
  1.  

2.4. Trouver les nombres premiers dans un intervalle

Une fois que l'on est en mesure de déterminer si un nombre est premier ou non, on peut commencer à rechercher les nombres premiers.

2.4.1. Utiliser la fonction est_premier

Voici un exemple de programme qui permet de rechercher les nombres premiers dans un intervalle donné. On passe en paramètre du programme
Warning: file_get_contents(polytech/trouve_premiers_fonction.py): Failed to open stream: No such file or directory in /home/jeanmichel.richer/public_html/ez_web.php on line 397

Afficher le code    polytech/trouve_premiers_fonction.py
  1.  

Voici quelques résultats qui permettent de comparer la méthode naïve avec la méthode améliorée :

 Méthode   temps (s)   somme 
 naïve   4m13s   454396537 
 améliorée   0,1   454396537 
Recherche des nombres premiers entre 1 et 10000 sur Intel i7-4790 CPU @ 3.60GHz

2.4.2. Crible d'Erathostène

Une autre solution, plutôt que de déterminer si un nombre $n$ est premier, consiste à utiliser un tableau de booléens tableau_nombres_premiers où chaque tableau_nombres_premiers[i] est vrai si $i$ est un nombre premier.

Pour remplir le tableau, on procède ainsi :

  • on indique qu'initialement tous les nombres sont premiers excepté 0 et 1
  • on commence avec l'indice $i=2$ qui sera incrémenté
  • pour tout tableau_nombres_premiers[i] affecté à vrai, on affecte tous ses multiples à faux

Crible

fonction
Description remplir un tableau et éliminer les multiples

Warning: file_get_contents(polytech/nombres_premiers_crible.algo): Failed to open stream: No such file or directory in /home/jeanmichel.richer/public_html/ez_web.php on line 397
Afficher le code    polytech/nombres_premiers_crible.algo
  1.  

Exercice 2.1

Ecrire un programme Python très simple qui implante l'algorithme du crible.

On utilisera une liste de nombres entiers.

Voici un exemple qui utilise la librairie numpy (trouve_premiers_crible.py) mais on peut écrire quelque chose de beaucoup plus simple.