TP - Conjecture de Goldbach

publicité
TP - Conjecture de Goldbach.nb
1/3
Conjecture et comète de Goldbach
Nombre de façons d’écrire un nombre pair inférieur à 100000 comme la somme de deux nombres premiers
1) Présentation
La conjecture de Goldbach (Formulée en 1742 par Christian Goldbach et non démontrée à ce jour) assure que tout nombre pair
supérieurà 4 peut s'écrire d’au moins d’une façon comme la somme de deux nombres premiers.
Par exemple, 20 = 17 + 3 = 13 + 7 peut s’écrire de deux façons comme la somme de deux nombres premiers.
On notera gHnL le nombre de façons différentes d’écrire n comme la somme de deux nombres premiers (par exemple gH20L = 2).
L’objectif de ce TP est de représenter graphiquement et efficacement la fonction g sur un intervalle @4, 6, 8, ..., 2 nD avec n le plus
grand possible. Ce graphe est curieux et on l’appelle “Comète de Goldbach”.
2) Calcul de la liste des nombres premiers
Le crible d’Erathostène est le moyen le plus efficace pour calculer la liste des nombres premiers plus petit qu’un entier n donné. On
crée une liste s comprenenant tous les entiers, puis on élimine (en mettant à 0) tous les nombres non premiers
s=[0,1,2,...,n]
# tous les entiers pour commencer. Il est crucial que
s[k]=k.
pour p entre 2 et e n E:
si s[p] ≠0:
# c’est que p est un entier premier
s[2p]=s[3p]=...=0 # on met à 0 tous les multiples stricts de p de la liste s
resultat = la sous liste de s constituée des entiers > 1 de la liste s
TP - Conjecture de Goldbach.nb
2/3
Pour n = 30, voilà les valeurs successives de la liste s après l’itération “pour p”:
# Liste s initiale
s =
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
# La liste s à la fin de chaque itération de la boucle “pour p”
p = 2, s=[0,1,2,3,0,5,0,7,0,9,0,11,0,13,0,15,0,17,0,19,0,21,0,23,0,25,0,27,0,29,0]
p = 3, s=[0,1,2,3,0,5,0,7,0,0,0,11,0,13,0,0,0,17,0,19,0,0,0,23,0,25,0,0,0,29,0]
p = 4, s est inchangée car s[4] = 0
p = 5, s=[0,1,2,3,0,5,0,7,0,0,0,11,0,13,0,0,0,17,0,19,0,0,0,23,0,0,0,0,0,29,0]
# Et l’extraction finale des entiers > 1 de s qui sont les nombres premiers b 30
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Q1) Ecrire une fonction crible(n) (avec n entier) calculant la liste des nombres premiers inférieurs ou égaux à n. Tester.
3) Calcul de la liste des valeurs de la fonction g: première idée
On veut calculer la liste val_g HnL = @g@4D, g@6D, g@8D, ..., , g@2 nDD.
Il faut commencer par calculer la liste s = crible(2n) des nombres premiers b 2n.
Notons s = @2, 3, 5 ..., pns-1 D = [s[0],s[1],...,s[ns-1]] la liste des nombres premiers inférieurs ou égaux à 2 n. Par définition de g,
g H2 kL est le nombre de couples Hs@iD, s@jDL de la liste s qui vérifient 0 b j b i < ns et s@iD + s jD = 2 k. La première idée qui vient
est donc de coller à la définition en calculant gH2 kL pour k œ P1, nT.
fonction val1_g(n):
s = crible(2n)
ns = len(s)
res = ? # Initialisation de la liste res=[g(4), g(6),...,g(2n)]
pour k variant de 1 à n:
# On va calculer g(2k)
calculer le nombre NC de couples (s[i], s[j]) de la liste s qui vérifient
0bjbibns -1 et s[i]+s[j]=2k et placer NC au bon endroit dans res
résultat = res
Q2) Ecrire une fonction val1_g(n) (avec n entier) calculant la liste des nombres premiers inférieurs ou égaux à n.
Tester, on doit trouver val1_g(15) = [1, 1, 1, 2, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3]
4) Limites de cette première version du calcul des valeurs de g
La fonction ci-dessous permet de calculer la durée d’exécution de f(n), avec f fonction quelconque
import time
def duree(f, n):
""" durée d'exécution de f(n)"""
t = time.perf_counter()
f(n)
t = time.perf_counter() - t
rep = "Durée d'exécution de {0}({1}) = {2:.3g} s".format(f.__name__,n, t)
print(rep)
Q3) Calculer les durées avec f = va11_g et n = 100, 500, 1000: la patience est déjà mise à rude épreuve. Essayons d’évaluer la
complexité de cette fonction val1_g. L’instruction “if s[i]+s[j] == 2k:” est au cœur des trois boucles, comptons le nombre
n ns-1 i
N de fois qu’elle est exécutée. On a: N = S
S
k=2 i=0 j=0
ns ~
n*H2 nL3
n ns-1
S 1= S
n nsHns+1L
nsHns+1L
= Hn - 1L *
. Or (on l’admet),
2
2
k=2
S Hi + 1L = S
k=2 i=0
n3
2n
2n
n3
~
, Donc N ~
=
O
.
Si
l’on
note
f
HnL
=
, alors f H1000L ê f H100L º 444: il faut en théorie
lnH2 nL
lnHnL
2 Hln nL2
ln2 HnL
ln2 HnL
444 fois plus de temps pour avoir la réponse de val1_g(n) quand on passe de n = 100 à n = 1000. Vérifier que ce calcul théorique
est validé par les temps de calculs faits ci-dessus. Il faut trouver une autre idée pour calculer g.
TP - Conjecture de Goldbach.nb
3/3
5) Amélioration du calcul des valeurs de g
La bonne idée est de ne calculer qu’une seule fois chaque somme s@iD + s@jD. Cela donne:
fonction val2_g(n):
s = crible(2n)
ns = len(s)
res = ? # Initialisation de la liste res=[g(2), g(4),...,g(2n)]
res[0] = 1
# g(4) = 1 car 4 = 2 + 2
pour 1 b j b i b ns-1:
calculer k = s[i] + s[j] et modifier (en ajoutant 1) au bon terme de res si kb2n
résultat = res
Q4) Ecrire une fonction val2_g(n) (avec n entier) calculant la liste des nombres premiers inférieurs ou égaux à n.
Tester, on doit trouver val2_g(15) = [1, 1, 1, 2, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3]
ns-1 i
Le nombre N de calcul de s[i] + s[j] est N = S
ns-1
S 1 = S i = HHns - 1L nsL ê 2 = OIns2 M = O
i=1 j=1
i=1
n2
. On gagne un facteur n
ln2 HnL
pour la complexité et donc le temps de calcul, c’est énorme.
Vérifier concrètement en calculant la durée pour f = va12_g et n = 100, 1000, 10000.
Astuce pour encore accélérer l’exécution: Lorsque k > 2 n, on peut arrêter la boucle “for j” avec un break bien placé. Le gain de
temps est d’environ 30 %.
6) Le tracé de la comète de Goldbach
La comète est tout simplement le graphe de la fonction g.
import numpy as np
import matplotlib.pyplot as plt
def graphe_g(n):
""" graphe de k --> g(k) sur [4,6,..,2n]"""
plage_x = range(4, 2 * n + 1, 2)
plage_y = val2_g(n)
plt.plot(plage_x, plage_y, linestyle = "", marker=".", markersize = 1)
plt.xlabel("n")
plt.ylabel("g(n)")
plt.title("Comète de Goldbach pour n ≤ " + str(2*n))
plt.grid(True)
##
plt.savefig(‘Comète1.png’,dpi=200)
# Enregistrer la comète
plt.show()
Q5) Tracer et enregistrer la comète avec une valeur raisonnable de n (environ n b 50 000).
Q6) Que penser de la conjecture de Goldbach ?
Téléchargement