« Mathématiques avec Python et Ruby/Nombres pseudo-aléatoires en Ruby » : différence entre les versions

Contenu supprimé Contenu ajouté
DannyS712 (discussion | contributions)
m <source> -> <syntaxhighlight> (phab:T237267)
Ligne 5 :
Le traditionnel nombre pseudo-aléatoire compris entre 0 et 1 s'obtient avec
 
<sourcesyntaxhighlight lang="ruby">
puts(rand)
</syntaxhighlight>
</source>
 
Si on veut un nombre entier aléatoire, on peut mettre le nombre d'occurences possibles entre parenthèses après le ''rand''. Par exemple, pour lancer un dé à 6 faces, on obtient avec ''rand(6)'' un nombre entre 0 et 5. Donc pour lancer un dé, on fait
 
<sourcesyntaxhighlight lang="ruby">
puts(rand(6).succ)
</syntaxhighlight>
</source>
 
[[Fichier:Eine_Kopeke_-_Zar_Alexander_I_1821.jpg|320px|right]]
Ligne 25 :
En ''Ruby'' cela donne
 
<sourcesyntaxhighlight lang="ruby">
def binomial(n,p)
return ((1..n).select { |i| rand<p }).size
Ligne 32 :
 
10.times do puts(binomial(8,0.2)) end
</syntaxhighlight>
</source>
 
=Lancer de dés=
Ligne 40 :
Pour voir si le dé est équilibré, on peut le lancer quelques milliers de fois et compter combien de fois chaque face est sortie... ou laisser faire le travail par ''Ruby'':
 
<sourcesyntaxhighlight lang="ruby">
effectifs=[0]*6
n=6000
n.times do effectifs[rand(6)]+=1 end
puts(effectifs)
</syntaxhighlight>
</source>
 
==Deux dés==
Ligne 51 :
Pour lancer deux dés et additionner leurs résultats, on fait comme ci-dessus et on additionne. Seulement le tableau des effectifs est indexé de 0 à 10 (2 de moins que les résultats des lancers):
 
<sourcesyntaxhighlight lang="ruby">
effectifs=[0]*11
n=6000
n.times do effectifs[rand(6)+rand(6)]+=1 end
puts(effectifs)
</syntaxhighlight>
</source>
 
=Avec des cartes=
Ligne 64 :
Puisque le jeu de cartes est un tableau, il suffit de choisir un indice au hasard pour tirer une carte au hasard. Par prudence, on va faire semblant de ne pas savoir qu'il y a 32 cartes dans le jeu (et qu'elles sont numérotées de 0 à 31). On va tirer 3200 fois une carte d'un jeu de 32 et compter le nombre de fois qu'on a eu un as de pique. Pour cela on va utiliser un compteur du nombre de victoires (''gains'') et on va lui injecter une unité chaque fois que le nom de la carte est ''1 pique'':
 
<sourcesyntaxhighlight lang="ruby">
valeurs=[1,7,8,9,10,'Valet','Dame','Roi']
valeurs=valeurs.collect { |v| v.to_s}
Ligne 74 :
gains=(1..n).inject {|g,i| g+(univers[rand(univers.size)]=='1 pique' ? 1 : 0) }
puts(gains.to_f/n)
</syntaxhighlight>
</source>
 
==Tirer 5 cartes au hasard==
Ligne 80 :
Pour constituer une main de 5 cartes, il suffit ''a priori'' de faire 5 fois l'opération précédente:
 
<sourcesyntaxhighlight lang="ruby">
valeurs=[1,7,8,9,10,'Valet','Dame','Roi']
valeurs=valeurs.collect { |v| v.to_s}
Ligne 90 :
((1..5).to_a).collect{hand.push(univers[rand(univers.size)])}
puts(hand)
</syntaxhighlight>
</source>
 
Seulement il peut arriver qu'on ait deux fois l'as de pique dans la même main ! En effet le script précédent réalise un ''tirage avec remise'', pour lequel les calculs de probabilités sont plus faciles, mais irréaliste pour les jeux de cartes et le Loto. Ce dont on a besoin dans le cas présent, c'est d'un ''tirage sans remise'', qui se produira en enlevant les cartes au fur et à mesure qu'on les met dans la main de 5 cartes.
 
<sourcesyntaxhighlight lang="ruby">
valeurs=[1,7,8,9,10,'Valet','Dame','Roi']
valeurs=valeurs.collect { |v| v.to_s}
Ligne 109 :
 
puts(hand)
</syntaxhighlight>
</source>
 
Le jeu dont on a extrait les cartes est une variable locale, et à la fin de ce script il y a toujours 32 cartes dans l'univers.
Ligne 115 :
Ensuite on peut compter les carrés d'as parmi 10 000 parties:
 
<sourcesyntaxhighlight lang="ruby">
valeurs=[1,7,8,9,10,'Valet','Dame','Roi']
valeurs=valeurs.collect { |v| v.to_s}
Ligne 136 :
puts(carres.to_f/10000)
</syntaxhighlight>
</source>
 
On construit une liste avec les cartes de ''hand'' dont le nom commence par un ''1'' suivi d'un espace (les as), et lorsque la longueur de cette liste est égale à 4, on incrémente le compteur ''carres''. À la fin de l'exécution du script, on a donc le nombre de carrés d'as parmi les 10 000 tirages, et en le divisant par 10 000, on a la fréquence de ces carrés d'as. Elle est très faible !
Ligne 156 :
Pour mélanger un jeu de cartes, on peut construire une main de 32 cartes ! Ensuite on peut répéter l'expérience 1900 fois, et compter combien de fois il y a eu au moins une rencontre (le nombre de rencontres strictement positif), et enfin, par division par 1900, estimer la fréquence de ces rencontres, et la comparer avec le quotient de 12 par 19 donné par [[w:Leonhard Euler|Euler]]:
 
<sourcesyntaxhighlight lang="ruby">
valeurs=[1,7,8,9,10,'Valet','Dame','Roi']
valeurs=valeurs.collect { |v| v.to_s}
Ligne 179 :
puts(gains.to_f/1900)
puts(12.0/19)
</syntaxhighlight>
</source>
 
Un exemple de résultat sur 1900 jeux:
Ligne 191 :
La valeur exacte de la probabilité d'une rencontre est donnée par ''Euler'', dont la formule se traduit en ''Ruby'' par
 
<sourcesyntaxhighlight lang="ruby">
a=(1..32).inject {|p,n| p+(-1)**n/(1..n).inject(1) {|f,k| f*k}}
puts(1-1/a)
</syntaxhighlight>
</source>
 
et qui donne la valeur <math>\frac{3122594362778744887436077703535391}{11610685876768858763797949063535391}</math>...
Ligne 202 :
Pour calculer la valeur approchée de <math>\pi</math> par la [[w:Méthode de Monte-Carlo|méthode de Monte-Carlo]], on crée un nuage de points à coordonnées pseudo-aléatoires, et on compte combien d'entre eux sont à moins d'une unité de distance de l'origine du repère:
 
<sourcesyntaxhighlight lang="ruby">
points=(1..1000000).inject{|p,n| p+(Math.hypot(rand,rand)<1? 1 : 0) }
puts(points.to_f/1000000*4)
</syntaxhighlight>
</source>
 
Le résultat est correct à trois décimales près.