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 ?