• Aucun résultat trouvé

Corrigé du DS Info n°1 2019

N/A
N/A
Protected

Academic year: 2022

Partager "Corrigé du DS Info n°1 2019"

Copied!
7
0
0

Texte intégral

(1)

CORRIG´ E DU DS INFO n°1 - MINES 2019 - I. Pr´ eliminaires

Q1 -

from math import floor, ceil, log, sqrt print(log(0.5))

Q2 -

def sont_proches(x,y):

atol, rtol = 1e-5, 1e-8

return abs(x-y) <= atol + abs(y)*rtol

Q3 - On notera que la fonction de l’´enonc´e ne se termine pas lorsque b= 1 ! def mystere_recursif(x, b):

if x<b : return 0 else:

return 1+ mystere_recursif(x/b, b) def mystere_iteratif(x, b):

k = 0

while x >= b:

x = x/b k += 1 return k

print(mystere_recursif(1001, 10), mystere_iteratif(1001, 10)) 3 3

Q4 - On constate quemystere(x,b)renvoie le plus grand entier k tel que bk 6n.

Il s’agit donc de l’entier k tel que bk 6x < bk+1, c’est-`a-dire k6logb(x)< k+ 1 soit k=⌊logbx⌋ (on rappelle que logbx=lnlnxb).

Q5 - A la fin de la boucle` x1contient 105×10−5 etx2contient

105−1

P

k=0

10−5.

Si les calculs ´etaient exacts les deux contiendraient 1 . Mais ce n’est pas le cas car les nombres manipul´es sont des flottants, et les erreurs d’arrondi s’accumulent lors du calcul de la somme.

II. G´ en´ eration de nombres premiers

II.1. Approche syst´ ematique

Q6 - Une m´emoire vive de 4 Go, soit 4×109×8 bits permet d’enregistrer un tableau de 4×109×8 32 = 109

´el´ements.

Q7 - Comme il n’y a que deux valeurs pour un bool´een, on peut les coder par un seul bit, ce qui permettrait un gain m´emoire d’un facteur de 32.

Q8 - Les listes en Python commen¸cant `a l’indice 0 , et pour ´eviter un d´ecalage avec l’´enonc´e, j’ai utilis´e une liste de N+1 ´el´ements, l’´el´ement d’indice 0 ne servant pas. Ainsi, l’´el´ement d’indice i correspond exactement au nombre entier i.

(2)

from math import sqrt def erato_iter(N):

liste_bool = [True] * (N+1)

liste_bool[1] = False # 1 n'est pas premier

racine_entiere = int(sqrt(N) + 0.1) # +0.1 `a cause d'´eventuelles erreurs d'arrondi for i in range(2, racine_entiere+1): # +1 `a cause du range en Python

if liste_bool[i]:

for k in range(2*i, N+1, i):

liste_bool[k] = False return liste_bool

N = 50

liste = erato_iter(N)

print([i for i in range(2, N+1) if liste[i]])

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

Q9 - Si p est un nombre premier, la boucle for k ...qui consiste `a marquer comme faux les multiples de p diff´erents de p est effectu´ee j

N p

k fois.

La complexit´e totale est donc de l’ordre de P

p6N ppremier

N

p, soit, compte tenu de l’indication de l’´enonc´e, de l’ordre de Nln(ln(N).

Q10 - Soit b la base de num´eration et n le nombre de chiffres de N, c’est-`a-dire bn6N < bn+1.

Alors bnln(nlnb)6Nln(lnN))< bn+1ln((n+ 1) lnb) donc on peut dire que le r´esultat pr´ec´edent est un

O

(bnlnn).

II.2. G´ en´ eration rapide de nombres premiers

Q11 - D’apr`es l’´enonc´e, i d´ecrit J1 ;NK donc on aura A=

N−1

P

i=1

2i= 2N −2 .

Cependant, dans l’algorithme propos´e `a la questionQ12, i d´ecritJ0 ;NK; dans ce cas, A pourra prendre la valeur maximum 2N−1 .

Q12 - L’algorithme revient `a tirer au (pseudo-)hasard chaque bit du nombre `a construire.

from time import time def bbs(N):

p1 = 24375763 p2 = 28972763 M = p1 * p2 t = time()

xi = floor( (t-floor(t))*1e7 )

# La r´esolution de l'horloge est 10**-7 d'apr`es l'´enonc´e.

A = 0

for i in range(N):

if xi % 2 == 1:

A = A + 2**i

# Remarque : il serait plus efficace de calculer les puissances

# de 2 au fur et `a mesure.

xi = xi**2 % M return A

print(bbs(10)) 879

Q13 - Si l’on veut un nombre strictement inf´erieur `a nmax, il faut 2N −1 <nmax, ou encore 2N 6nmax. On devrait donc choisir N=mystere(nmax,2). Mais en faisant ainsi, les nombres entre 2N + 1 et nmaxs’il y en a (c’est-`a-dire sinmaxn’est pas une puissance de 2 ) ne seront jamais obtenus ; pour cette raison, j’ai choisi d’augmenter N de 1 , mais de tester ensuite sibbs(N)est bien inf´erieur `anmax.

(3)

Remarques

– La fonctionbbspeut renvoyer 0 ou 1 comme valeur de p; ces valeurs sont ´evidemment `a exclure.

– Le test de Fermat ne ne fonctionne pas pour a=p (cf. la condition a∈J2 ;p−1K dans l’´enonc´e). En effet, pp−1 ≡0 6≡1[p]. Ainsi par exemple le nombre 7 sera jug´e non premier par ce test et sera donc

´ecart´e. C’est la raison pour laquelle l’´enonc´e demande que nb max>12 : ainsi il y aura au moins un nombre premier qui soit >7 et <nb max (c’est 11).

from time import time

from math import sqrt, floor, ceil, log def erato_iter(N):

liste_bool = [True for i in range(N+1)]

liste_bool[1] = False # 1 n'est pas premier

racine_entiere = int(sqrt(N) + 0.1) # +0.1 `a cause d'´eventuels erreurs d'arrondi for i in range(2, racine_entiere+1): #+1 `a cause du range en Python

if liste_bool[i]:

for k in range(2*i, N+1, i):

liste_bool[k] = False return liste_bool

def mystere(x, b):

if x<b : return 0 else:

return 1+ mystere(x/b, b) def bbs(N):

# version un peu am´elior´ee p1 = 24375763

p2 = 28972763 M = p1 * p2 t = time()

xi = floor( (t-floor(t))*1e7 ) A = 0

puiss = 1 # les puissances de 2 for i in range(N):

if xi % 2 == 1:

A += puiss puiss *= 2 xi = xi**2 % M return A

def test_Fermat(p):

for a in [2, 3, 5, 7]:

# if a**(p-1) % p != 1: # horriblement lent!

if pow(a, p-1, p) != 1: # bien plus rapide car tous les calculs

# avec pow sont faits modulo p au fur et `a mesure return False

return True

def premier_rapide(n_max):

# N = mystere(n_max, 2) + 1

N = ceil( log(n_max, 2) ) # plus rapide!

p = bbs(N)

while p < 2 or p >= n_max or not test_Fermat(p):

p = bbs(N) return p

def stats_bbs_fermat(N, nb):

(4)

premier = erato_iter(N) erreurs = []

for k in range(nb):

p = premier_rapide(N) if not premier[p]:

erreurs.append(p) return erreurs, len(erreurs)/nb deb = time()

print(stats_bbs_fermat(100000, 50000)) print('Temps:', time() - deb)

([], 0.0)

Temps: 10.945600986480713

Q14 - Voir ci-dessus.

III. Compter les nombres premiers

III.1. Calcul de π ( n ) via un crible

Q15 -

from math import sqrt, log def erato_iter(N):

liste_bool = [True for i in range(N+1)]

liste_bool[1] = False # 1 n'est pas premier

racine_entiere = int(sqrt(N) + 0.1) # +0.1 `a cause d'´eventuels erreurs d'arrondi for i in range(2, racine_entiere+1): #+1 `a cause du range en Python

if liste_bool[i]:

for k in range(2*i, N+1, i):

liste_bool[k] = False return liste_bool

def Pi(N):

premier = erato_iter(N) res = []

pi_n = 0

for n in range(1,N+1):

if premier[n]:

pi_n += 1

res.append( [n, pi_n] ) return res

def verif_Pi(N):

valeurs = Pi(N)[5392:]

for (n, pi_n) in valeurs:

if n/(log(n)-1) >= pi_n:

return False return True

print(Pi(8))

print(verif_Pi(100000))

[[1, 0], [2, 1], [3, 2], [4, 2], [5, 3], [6, 3], [7, 4], [8, 4]]

True Q16 - Voir ci-dessus.

(5)

III.2. Calcul approch´ e via une int´ egrale g´ en´ eralis´ ee

III.2.1. Estimation de li par quadrature num´erique

Q17 - Pour obtenir un r´esultat approch´e convenable par la m´ethode des rectangles, il faut quepassoit tr`es petit.

Ainsi, il est pertinent d’exprimer la complexit´e en fonction depaslorsque celui-ci tend vers 0.

L’op´eration ´el´ementaire la plus couteuse est sans doute l’appel `a la fonction `a int´egrer, qui est en

O

(1)

d’apr`es l’´enonc´e. Il y a un tel appel pour chaque rectangle de la subdivision, et il y a pasx rectangles. D’o`u une complexit´e en

O

x

pas

.

Q18 - Les m´ethodes des rectangles centr´es et des trap`ezes ont la mˆeme complexit´e que celle des rectangles `a droite (mˆeme nombre de points calcul´es, `a 1 pr`es).

Q19 -

from math import log

from scipy.special import expi #exponentielle int´egrale def inv_ln_rect_d(a, b, pas):

# on ´evite les multiplications:

# ce serait tr`es maladroit d'´ecrire une boucle for avec des a+k*pas S = 0

a0 = a + pas while a0 <= b:

S += 1/log(a0) a0 += pas return pas * S

def inv_ln_rect_g(a, b, pas):

# m´ethode des rectangles `a gauche S = 0

a0 = a

while a0 < b:

S += 1/log(a0) a0 += pas return pas * S def li_d(x, pas):

if x>1:

return inv_ln_rect_d(0, 1-pas, pas) + inv_ln_rect_d(1+pas, x, pas) elif x==1:

return float('inf') else:

return inv_ln_rect_d(0, x, pas) def li_d_modif(x, pas):

if x>1:

return inv_ln_rect_d(0, 1-pas, pas) + inv_ln_rect_g(1+pas, x, pas) elif x==1:

return float('inf') else:

return inv_ln_rect_d(0, x, pas) def li_d_modif2(x, pas):

if x>1:

return inv_ln_rect_d(0, 1-2*pas, pas) + inv_ln_rect_d(1+pas, x, pas) elif x==1:

return float('inf') else:

return inv_ln_rect_d(0, x, pas) for x in [0.5, 1.1, 1.45, 10, 100]:

(6)

print("Pour x = ",x,":")

print("li_d:{:.6f}, li_d_modif:{:.6f}, li_d_modif2:{:.6f}, Exact:{:.6f}".format(li_d(x, 1e-5 Pour x = 0.5 :

li_d:-0.378663, li_d_modif:-0.378663, li_d_modif2:-0.378663, Exact:-0.378671 Pour x = 1.1 :

li_d:-2.675835, li_d_modif:-1.675830, li_d_modif2:-1.675840, Exact:-1.675773 Pour x = 1.45 :

li_d:-1.003703, li_d_modif:-0.003698, li_d_modif2:-0.003708, Exact:-0.003680 Pour x = 10 :

li_d:5.165592, li_d_modif:6.165597, li_d_modif2:6.165587, Exact:6.165600 Pour x = 100 :

li_d:29.126131, li_d_modif:30.126136, li_d_modif2:30.126126, Exact:30.126142 Q20 - Voir ci-dessus.

III.2.2. Analyse des r´esultats deli d

Q21 - L’´ecart relatif pr´esente une asymptote en une valeur proche de 1,4 tout simplement car son calcul fait intervenir une division parli refqui s’annule (visible sur la figure 1).

Plus pr´ecis´ement, la fonctionlis’annule en µ≈1.4513692348... qui est la constante de Soldner.

Q22 - L’int´egrale ´etant consid´er´ee au sens de Cauchy, on a Z 1+ε

1−ε

dt ln(t) =

Z ε

−ε

du

ln(1 +u) =

O

(ε) lorsque ε→0 ; en effet, en ´ecrivant un d´eveloppement limit´e de ln au voisinage de 1 `a l’ordre 2 on a

Z −h

−ε

du ln(1 +u) =

Z −h

−ε

1 u+1

2+

O

(u)

du et de mˆeme

Z ε

h

du ln(1 +u) =

Z ε

h

1 u+1

2+

O

(u)

du donc lim

h→0+

Z −h

−ε

du ln(1 +u)+

Z ε

h

du ln(1 +u)

!

=ε+

O

2). Ainsi,

Z 1+ε

1−ε

dt ln(t)

ε→0ε.

Or on voit sur la figure 4 que, avec la m´ethode des rectangles `a droite, la valeur de x7→ ln1x en 1−ε n’est pas ”compens´ee” par la valeur en 1 +ε, ce qui explique l’´ecart.

Q23 - Une solution (li modif) consiste donc `a utiliser la m´ethode des rectangles `a gauche pour la partie droite de la courbe. Une autre solution (li modif2) consiste `a retirer un rectangle dans la m´ethode des rectangles

`a droite pour la partie gauche de la courbe.

Tout cela fait un peu bidouillage... Pourquoi utiliser la m´ethode des rectangles, qui est la pire ?

III.3. Estimation de li via Ei

Q24 - Pour obtenir une complexit´e en O(MAXIT), il faut penser `a calculer les factorielles et les puissances de x en les gardant en m´emoire au fur et `a mesure (c’est de toutes fa¸cons un principe de base !).

from math import log

from scipy.special import expi #exponentielle int´egrale def sont_proches(x,y):

atol, rtol = 1e-5, 1e-8

return abs(x-y) <= atol + abs(y)*rtol MAXIT = 100

def Ei(x):

if x<=0:

return False else :

gamma = 0.577215664901 n = 1

fact = 1 # n!

puiss = x # x**n

Ei0 = gamma + log(x) # ordre n-1

(7)

Ei1 = Ei0 + x # ordre n

while n <= MAXIT and not sont_proches(Ei0, Ei1):

n += 1 fact *= n puiss *= x Ei0 = Ei1

Ei1 += puiss/n/fact if n == MAXIT+1:

return False else:

return Ei1 def li_dev(x):

return Ei(log(x))

x = 10; print(li_dev(x), expi(log(x))) 6.165598760535916 6.1655995047872985

IV. ´ Evaluation des performances (BDD)

Q25 - Plusieurs enregistrements ont la mˆeme valeur pour le champnom, ce ne peut donc pas ˆetre une cl´e primaire.

Q26 - 1. Nombre d’ordinateurs disponibles et quantit´e moyenne de m´emoire vive.

SELECT COUNT(∗) AS n b o r d i , AVG(RAM) AS RAM moyenne FROM o r d i n a t e u r s

2. Noms des PC sur lesquels l’algorithmerectanglesn’a pas ´et´e test´e pour la fonctionli.

SELECT t e s t e s u r FROM f o n c t i o n s

WHERE a l g o r i t h m e <> ” r e c t a n g l e s ” OR nom <> ” l i ” GROUP BY t e s t e s u r

ou bien :

SELECT nom FROM o r d i n a t e u r s WHERE nom NOT IN (

SELECT t e s t e s u r FROM f o n c t i o n s

WHERE a l g o r i t h m e=” r e c t a n g l e s ” AND nom = ” l i ” )

3. Pour chaque test de Ei garder le nom de l’algo, du pc, et sa puissance. Trier du plus lent au plus rapide.

SELECT a l g o r i t h m e , t e s t e s u r , ram , g f l o p s

FROM f o n c t i o n s JOIN o r d i n a t e u r s ON f o n c t i o n s . t e s t e s u r = o r d i n a t e u r s . nom WHERE f o n c t i o n s . nom = ” Ei ”

ORDER BY t e m p s e x e c DESC ou, plus simplement `a mon avis :

SELECT a l g o r i t h m e , t e s t e s u r , ram , g f l o p s FROM f o n c t i o n s , o r d i n a t e u r s

WHERE f o n c t i o n s . t e s t e s u r = o r d i n a t e u r s . nom AND f o n c t i o n s . nom = ” Ei ” ORDER BY t e m p s e x e c DESC

Références

Documents relatifs

Donner la mesure de l’angle marqué en justifiant

La fonction est du signe du coefficient de à l’extérieur des racines, et du signe contraire entre

L’ion dichromate est rouge-orangé, l’ion chrome III est vert, les autres espèces sont incolores ; à l’état final, il s’est formé des ions chrome III mais il reste des

D’après l’équation de la réaction, on constate que les ions oxonium sont ‘’remplacés’’ par les ions calcium or les ions oxonium ont une plus grande conductivité

Par exemple, l’application de cette fonction ` a la liste illustr´ee par la Figure 3(a) permet d’obtenir soit la liste illustr´ee par la Figure 3(b) lorsque l’on

La fonction qui suit utilise deux listes : groupes qui contient les groupes en voie de formation et rep qui contient les repr´esentants des groupes d´ej` a rencontr´es.. Pour

[r]

[r]