1. n est de type int (entier). Si x ∈ [0,1[, alors 0 ≤ (h+2)/2× x < (h+2

publicité
C ORRIG&Eacute; S UJET 0 M INES
1. n est de type int (entier). Si x ∈ [0, 1[, alors 0 ≤ ( h + 2)/2 &times; x &lt; ( h + 2)/2, donc n est un entier tel
h
que : 0 ≤ n &lt; + 2.
2
2. def c a l c u l _ n ( h ) :
i f h&gt;1 :
return i n t ( ( h + 2 . 0 ) / 2 * random ( ) ) + 1
else :
return 0
3. Petite difficult&eacute; : si on ne fait rien, toute variable piles d&eacute;finie dans le corps de la fonction est
locale et sera &quot;d&eacute;truite&quot; &agrave; la fin de l’ex&eacute;cution. On rend une variable &quot;globale&quot; en la d&eacute;clarant, &agrave;
l’aide du mot-cl&eacute; &quot;global&quot;.
def i n i t i a l i s a t i o n (P ) :
global piles
p i l e s = [ 0 ] *P
M&eacute;thodes alternatives pour cr&eacute;er la liste [0, &middot; &middot; &middot; , 0] :
p i l e s =[0 f o r i in range ( P ) ]
ou
piles =[]
f o r i in range (P ) :
p i l e s . append ( 0 )
On &eacute;vite le probl&egrave;me de la variable globale en d&eacute;finissante une fonction qui renvoie une liste
[0, &middot; &middot; &middot; , 0], on ne d&eacute;finit piles que dans le programme principal :
def i n i t i a l i s a t i o n (P)
return [ 0 ] * P
p i l e s = i n i t i a l i s a t i o n ( 1 0 0 ) # par exemple
Rappel cours :
Les variables cr&eacute;&eacute;es par une fonction sont, par d&eacute;faut, locales, et masquent (sans les &quot;&eacute;craser&quot;) les
variables globales de m&ecirc;me nom. Elles sont &quot;d&eacute;truites&quot; &agrave; la fin de l’&eacute;valuation. Les param&egrave;tres
formels de la fonction sont des variables locales qui sont initialis&eacute;es avec la m&ecirc;me identit&eacute; (et
en particulier la m&ecirc;me valeur) que les arguments pass&eacute;s &agrave; la fonction. Il n’est pas interdit de
modifier leur valeur pendant l’&eacute;valuation, mais &agrave; la fin de l’&eacute;valuation, ces modifications ne sont
pas conserv&eacute;es car les variables locales sont d&eacute;truites. Deux exceptions : La d&eacute;claration &quot;global&quot;
permet &agrave; la fonction de cr&eacute;er et modifier des variables globales, ces modifications &eacute;tant conserv&eacute;es
apr&egrave;s l’&eacute;valuation de la fonction. Quand l’argument est une liste (type &quot;mutable&quot;), les modifications apport&eacute;es &agrave; ses termes sont conserv&eacute;es, car elle conserve son identit&eacute;, ce sont les identit&eacute;s
des termes qui changent (ce n’est pas le cas si on r&eacute;-affecte directement la liste).
En Python, les listes (et les dictionnaires) sont mutables. Attention : les entiers, les floats, mais
aussi les strings et les tuples ne sont pas mutables !
4. def a c t u a l i s e ( p i l e s , perdus ) :
g l o b a l perdus # pas n &eacute; c e s s a i r e pour une l i s t e
f o r p in range ( len ( p i l e s ) − 1 ) :
h= p i l e s [ p+1] − p i l e s [ p ]
i f h&gt;1:
n= c a l c u l _ n ( h )
p i l e s [ p ] −= n
p i l e s [ p+1] +=n
h= p i l e s [ − 1]
n= c a l c u l _ n ( h )
p i l e s [ − 1] −= n
perdus +=n
5. L’utilisateur entre P &agrave; l’aide de la commande &quot;input&quot;. Attention, input lit ce qu’on entre au clavier
comme une cha&icirc;ne. Il faut penser &agrave; convertir en entier.
P= i n t ( input ( &quot; nombre de p i l e s &quot; ) )
i n i t i a l i s a t i o n (P)
n b _ i n s t r u c t i o n s =0
perdus=0
while ( perdus &lt;1000):
i f n b _ i n s t r u c t i o n s % 10 ==0 :
p i l e s [ 0 ] +=1
a c t u a l i s e ( p i l e s , perdus )
6. Pour tracer une courbe connaissant une liste x d’abscisses et y d’ordonn&eacute;es, on utilise la fonction
plot de la biblioth&egrave;que matplotlib.pyplot (abr&eacute;g&eacute;e en plt).
x =[ i f o r i in range (P ) ] # ou bien x= np . arange ( P )
y= p i l e s
plt . plot (x , y )
Si on se contente de fournir une liste, les indices sont pris comme listes d’abscisses, les termes
comme liste d’ordonn&eacute;es, ce qui simplifie le code :
plt . plot ( piles )
7. L’intitul&eacute; des colonnes est trompeur : Votant sans &quot;s&quot;, et aucune r&eacute;p&eacute;tition dans cette colonne. La
colonne Votant contient bien le nombre de votants qu’il y a dans chaque laboratoire, la requ&egrave;te
est donc naturellement :
SELECT
densite , R, Kn, Gamma, Kt , mu
FROM granular_base
WHERE mat = &quot; verre &quot; AND geom = &quot; sphere &quot; AND note &gt;= 3
AND Votant &gt;=3;
8. On d&eacute;finit une classe &quot;grain&quot;. Pour cr&eacute;er une instance (c-&agrave;-d., un objet de cette classe), on utilise
la syntaxe G=grain(x,y), ce qui appelle en r&eacute;alit&eacute; la fonction __init__(G,x,y) et initialise un grain G
poss&eacute;dant les attributs : G.pos (position) de valeur initiale ( x, y), G.vit (vitesse) de valeur initiale
(0, 0), G.force (force d’interaction) de valeur initiale (0, 0).
9. Les grains sont empil&eacute;s comme sur le sch&eacute;ma :
2/ 4
10. Les erreurs d’arrondis font qu’il n’est pas possible num&eacute;riquement d’avoir une distance entre
les grains qui soit exactement de 2R .
11. hypotenuse = s q r t ( ( Xi −Xj ) * * 2 + ( Yi −Yj ) * * 2 )
cos_alpha = ( Xj −Xi ) / hypotenuse
sin_alpha = ( Yj −Yi ) / hypotenuse
12. def somme_int ( ) : # sommation pour chaque grain des i n t e r a c t i o n s
f o r i in range ( len ( tas ) ) :
f o r j in range ( len ( tas ) ) :
i f j != i :
Fjin , F j i t = calcul_Fnt ( i , j )
F j i x = F j i n * cos_alpha − F j i t * sin_alpha
F j i y = F j i n * sin_alpha + F j i t * cos_alpha
tas [ i ] . f o r c e [ 0 ] += F j i x
tas [ i ] . f o r c e [ 1 ] += F j i y
13. En consid&eacute;rant, l’acc&eacute;l&eacute;ration constante &eacute;gale &agrave; a k sur l’intervalle ]( k − 1/2)∆ t, ( k + 1/2)∆ t[, on
obtient une approximation &agrave; l’ordre 1 de la vitesse vk+1/2 ; de m&ecirc;me, en consid&eacute;rant la vitesse
constante &eacute;gale &agrave; vk+1/2 sur l’intervalle ] k∆ t, ( k + 1)∆ t[, on obtient une approximation &agrave; l’ordre 1
de la position xk :
(
vk+1/2 = vk−1/2 + a k ∆ t
xk+1 = xk + vk+1/2 ∆ t
14. Delta_t = T_stop / i n c
f o r k in range ( i n c ) :
somme_int ( )
f o r i in range ( len ( tas ) ) :
Fix , Fiy=tas [ i ] . f o r c e
mi = M
ax = Fix / mi
ay = Fiy / mi−g
x , y = tas [ i ] . pos
vx , vy = tas [ i ] . v i t
vx += ax * Delta_t
x += vx * Delta_t
vy += ay * Delta_t
y += vy * Delta_t
tas [ i ] . pos = x , y
tas [ i ] . v i t = vx , vy
15. Dans tout sch&eacute;ma d’int&eacute;gration num&eacute;rique, on approche la courbe entre deux instants par une
courbe plus simple (ici, un segment). Il faut bien chosir le pas car :
augmenter le pas augmente le risque d’un &eacute;cart entre la courbe et son approximation ;
diminuer le pas augmente le temps de calcul et les accumulations d’erreurs d’arrondi.
16. L’introduction du terme d’ordre 1 est probl&eacute;matique car dans la m&eacute;thode, la vitesse est calcul&eacute;e
en fonction de l’acc&eacute;l&eacute;ration. On r&eacute;sout le probl&egrave;me en calculant a k en fonction de vk−1/2 , c’est-&agrave;dire :
ax
ay
vx
x
= Fix / mi − 1/ tau / mi * vx
= Fiy / mi − 1/ tau / mi * vy −g
+= ax * Delta_t
+= vx * Delta_t
3/ 4
vy += ay * Delta_t
y += vy * Delta_t
mais on a une m&eacute;thode proche de celle d’Euler. Il vaut mieux approcher : vk =
obtient la formule de r&eacute;currence :
&micro;
&para;
&micro;
&para;
∆t
∆t
F
1+
vk+1/2 = 1 −
vk−1/2 +
∆t
2τ m i
2τ m i
mi
vk−1/2 + vk+1/2
. On
2
Il est pr&eacute;f&eacute;rable de choisir ∆ t petit devant τ m i .
17. Le calcul de somme_int() est quadratique (2 boucles imbriqu&eacute;es).
18. Un grain de sable semble n’interagir qu’avec (environ) 6 autres grains. Si on a un acc&egrave;s direct &agrave;
ces grains-l&agrave;, on peut esp&eacute;rer une complexit&eacute; de l’ordre de 6 n, donc lin&eacute;aire, pour cette partie de
l’algorithme.
19. ? ? ?
4/ 4
Téléchargement