Médaille
N°1 pour apprendre & réviser du collège au lycée.
Planche de Galton - Python
Fiche méthode

Introduction :

Dans cette fiche, nous allons illustrer un schéma de Bernoulli, avec un algorithme simulant une « planche de Galton ».
Après avoir expliqué en quoi consiste cette planche et montré le lien avec la loi binomiale, nous programmerons étape par étape l’algorithme en Python.

Planche de Galton et schéma de Bernoulli

Principe de la planche de Galton

La planche de Galton fut inventée par le statisticien – entre autres choses – Francis Galton (1822-1911), afin d’illustrer un schéma de Bernoulli.

Il s’agit d’une planche verticale, sur laquelle sont plantés plusieurs rangées de clous (voir exemple infra).
On lâche une bille en haut : celle-ci rencontre un clou sur chaque rangée et, à chaque fois, elle va à gauche ou à droite du clou, avec une probabilité de 0,50,5 pour les deux options.
Enfin, un réservoir numéroté, en bas de la planche, recueille la bille.

  • Représentons cette planche, avec 44 rangées de clous (points bleus) et donc 55 réservoirs (de manière générale, s’il y a nn rangées de clous, il y a n+1n+1 réservoirs) :

Alt mathématiques terminale algorithme Python planche de Galton Cette représentation n’est pas l’échelle

L’idée est de lancer un grand nombre de billes, puis de compter le nombre de billes contenues dans chaque réservoir, avant de calculer les fréquences correspondantes.

Schéma de Bernoulli et loi binomiale

Prenons une planche de Galton de nn rangées de clous (nNn\in \mathbb N ^*).
La bille rencontre le premier clou : elle passe à gauche avec une probabilité de 0,50,5, à droite avec la même probabilité. Nous considérons que, si la bille passe à droite, c’est un succès ; un échec si elle passe à gauche.

  • Nous reconnaissons une épreuve de Bernoulli, de paramètre p=0,5p=0,5.

Il en va de même pour chaque clou rencontré ensuite sur les nn rangées : les probabilités que la bille passe à gauche ou à droite ne dépendent pas du clou de la rangée précédente et restent toujours égales à 0,50,5.

  • Il s’agit donc d’un schéma de Bernoulli, de paramètres nn et p=0,5p=0,5.

Soit XX la variable aléatoire qui compte le nombre de succès, c’est-à-dire le nombre de fois que la bille passe à droite d’un clou.

  • XX suit une loi binomiale de paramètres nn et p=0,5p=0,5.

Si nous reprenons l’exemple de la planche avec 44 rangées, nous voyons que :

  • si la bille va 0\red 0 fois à droite, elle finit dans le réservoir 0\red 0 ;
  • si elle va 1\green 1 fois à droite – peu importe à quelle rangée –, elle finit dans le réservoir 1\green 1 ;
  • si elle va 2\purple 2 fois à droite – peu importe à quelles rangées –, elle finit dans le réservoir 2\purple 2 ;
  • si elle va 3\blue 3 fois à droite – peu importe à quelles rangées –, elle finit dans le réservoir 3\blue 3 ;
  • si elle va 4\textcolor{#FFA500} 4 fois à droite, elle finit dans le réservoir 4\textcolor{#FFA500} 4.
  • Ainsi, de manière générale, XX donne aussi le numéro du réservoir qui recueille la bille.

Donnons la loi de probabilité de XX, en utilisant la formule que nous avons apprise.

  • Pour tout k{0,1,2,3,4}k\in \lbrace 0,\,1,\,2,\,3,\,4\rbrace :

p(X=k)=(4k)×0,5k×0,54k=(4k)×0,54\begin{aligned} p(X=k)&=\begin{pmatrix} 4 \ k \end{pmatrix}\times 0,5^k\times 0,5^{4-k} \ &=\begin{pmatrix} 4 \ k \end{pmatrix} \times 0,5^4 \end{aligned}

kk 00 11 22 33 44
p(X=k)p(X=k) 0,06250,0625 0,250,25 0,3750,375 0,250,25 0,06250,0625
bannière astuce

Astuce

Nous pouvons bien sûr aussi utiliser une calculatrice ou un tableur pour calculer ces différentes probabilités.

Simulation de la planche de Galton par un algorithme Python

Préambule

Pour simuler la direction aléatoire que prend la bile à chaque clou, nous nous servirons de la fonction randint(p, q)\purple{\text{randint(p, q)}} (p\purple{\text{p}} et q\purple{\text{q}} des entiers tels que p<q\purple{\text{p}} < \purple{\text{q}}), qui fait partie du module random\purple{\text{random}}.

  • Cette fonction renvoie de manière aléatoire un nombre entier compris entre p\purple{\text{p}} et q\purple{\text{q}} inclus.

Nous donnerons le nombre de billes présentes dans chaque réservoir sous la forme d’une liste : l’élément 00 de la liste donnera le nombre de billes présentes dans le réservoir 00 ; l’élément 11 celui dans le réservoir 11, etc.

Algorithme

  • Nous commençons par importer la fonction randint\purple{\text{randint}} du module random\purple{\text{random}}, puisque nous allons en avoir besoin :

1from random import randint\textcolor{#A9A9A9}{\text{1}}\quad\text{from random import randint}
  • Nous définissons notre fonction Python galton\purple{\text{galton}} qui simule la planche de Galton. Nous souhaitons pouvoir choisir le nombre de rangées de clous n\purple{\text{n}} et le nombre de billes à lâcher b\purple{\text{b}}.
  • La fonction prend donc ces données en paramètres.

3def galton(n,b):\textcolor{#A9A9A9}{\text{3}}\quad\text{def galton(n,b):}
  • Nous créons la liste R\purple{\text{R}}, qui donnera le nombre de billes présentes dans chaque réservoir après les b\purple{\text{b}} lâchers.

Nous l’avons vu plus haut, s’il y a n\purple{\text{n}} rangées de clous, il y a n + 1\purple{\text{n + 1}} réservoirs.

  • La liste est donc de longueur n + 1\purple{\text{n + 1}}, nous l’initialisons bien sûr avec 0\purple{\text{0}} bille dans chacun des réservoirs.

4R = [0 for i in range(n + 1)]\textcolor{#A9A9A9}{\text{4}}\quad\qquad\text{R = [0 for i in range(n + 1)]}
  • Nous simulons les b\purple{\text{b}} lâchers de bille par une boucle for\purple{\text{for}} :

5for j in range(b):\textcolor{#A9A9A9}{\text{5}}\quad\qquad\text{for j in range(b):}
  • Nous initialisons la variable S\purple{\text{S}}, qui donnera le numéro du réservoir qui recueillera la bille.

6S = 0\textcolor{#A9A9A9}{\text{6}}\quad\qquad\qquad\text{S = 0}
  • Nous simulons le franchissement des n\purple{\text{n}} rangées de clous rencontrées par la bille par une nouvelle boucle for\purple{\text{for}} :

7for k in range (n):\textcolor{#A9A9A9}{\text{7}}\quad\qquad\qquad\text{for k in range (n):}
  • Nous nous servons ensuite de la fonction randint\purple{\text{randint}} pour simuler le choix aléatoire de la gauche ou de la droite.

Si le résultat est 00, nous considérons que la bille va à gauche. S’il est 11, nous considérons qu’elle va à droite. Nous comptons ainsi les « succès », en ajoutant ce résultat à la variable S\purple{\text{S}} à chaque tour de boucle (soit à chaque clou rencontré).

  • Et, nous l’avons dit dans la première partie, le contenu final de S\purple{\text{S}} donnera le numéro du réservoir où finit la bille.

8S = S + randint(0, 1)\textcolor{#A9A9A9}{\text{8}}\quad\qquad\qquad\qquad\text{S = S + randint(0, 1)}
  • Une fois la bille arrivée dans un réservoir, nous mettons à jour la liste R\purple{\text{R}} en indiquant qu’il y a 11 bille supplémentaire dans le réservoir S\purple{\text{S}} :

9R[S] = R[S] + 1\textcolor{#A9A9A9}{\text{9}}\quad\qquad\qquad \text{R[S] = R[S] + 1}
  • Ce qui nous intéresse, c’est la fréquence avec laquelle une bille finit dans chacun des réservoirs.
  • Nous créons à cet effet une nouvelle liste, que nous nommons F\purple{\text{F}}, que nous initialisons vide :

10F = []\textcolor{#A9A9A9}{\text{10}}\quad\qquad \text{F = []}
  • Cette liste sera de la même longueur que R\purple{\text{R}}, soit n + 1\purple{\text{n + 1}} :

11for l in range(n + 1):\textcolor{#A9A9A9}{\text{11}}\quad\qquad \text{for l in range(n + 1):}
  • Puisque F\purple{\text{F}} contiendra les fréquences, chacun de ses coefficients se calcule en divisant le nombre de billes arrivées dans le réservoir l\purple{\text{l}}, soit R[l]\purple{\text{R[l]}}, divisé par le nombre de billes lâchées, soit b\purple{\text{b}} :

12F.append(R[l] / b)\textcolor{#A9A9A9}{\text{12}}\quad\qquad\qquad \text{F.append(R[l] / b)}
  • Finalement, nous affichons la répartition des billes après que l’ensemble des lâchers ont été effectués :

13print(R)\textcolor{#A9A9A9}{\text{13}}\quad\qquad \text{print(R)}
  • Et nous affichons enfin les fréquences correspondantes :

14print(F)\textcolor{#A9A9A9}{\text{14}}\quad\qquad \text{print(F)}
  • L’algorithme est terminé :

1from random import randint23def galton(n,b):4R = [0 for i in range(n + 1)]5for j in range(b):6S = 07¨C11Cfor k in range (n):8¨C12C¨C13C¨C14C¨C15CS = S + randint(0, 1)9¨C16C¨C17C¨C18CR[S] = R[S] + 110¨C19C¨C20CF = []11¨C21C¨C22Cfor l in range(n + 1):12¨C23C¨C24C¨C25CF.append(R[l] / b)13¨C26C¨C27Cprint(R)14¨C28C¨C29Cprint(F)\begin{aligned} \textcolor{#A9A9A9}{\text{1}}&\quad\text{from random import randint} \ \textcolor{#A9A9A9}{\text{2}}& \ \textcolor{#A9A9A9}{\text{3}}&\quad\text{def galton(n,b):} \ \textcolor{#A9A9A9}{\text{4}}&\quad\qquad\text{R = [0 for i in range(n + 1)]} \ \textcolor{#A9A9A9}{\text{5}}&\quad\qquad\text{for j in range(b):} \ \textcolor{#A9A9A9}{\text{6}}&\quad\qquad\qquad\text{S = 0} \ \textcolor{#A9A9A9}{\text{7}}&\quad\qquad\qquad\text{for k in range (n):} \ \textcolor{#A9A9A9}{\text{8}}&\quad\qquad\qquad\qquad\text{S = S + randint(0, 1)} \ \textcolor{#A9A9A9}{\text{9}}&\quad\qquad\qquad\text{R[S] = R[S] + 1} \ \textcolor{#A9A9A9}{\text{10}}&\quad\qquad\text{F = []} \ \textcolor{#A9A9A9}{\text{11}}&\quad\qquad\text{for l in range(n + 1):} \ \textcolor{#A9A9A9}{\text{12}}&\quad\qquad\qquad\text{F.append(R[l] / b)} \ \textcolor{#A9A9A9}{\text{13}}&\quad\qquad\text{print(R)} \ \textcolor{#A9A9A9}{\text{14}}&\quad\qquad\text{print(F)} \end{aligned}
bannière exemple

Exemple

Considérons une planche avec 66 rangées de clous et 77 réservoirs, et simulons le lâcher de 10001\,000 billes.
Nous entrons : galton(6,1000)\purple{\text{galton(6,1000)}}

  • L’algorithme nous retourne, par exemple :

[11, 98, 239, 305, 267, 66, 14][0.011, 0.098, 0.239, 0.305, 0.267, 0.066, 0.014]\begin{aligned} &\purple{\text{[11, 98, 239, 305, 267, 66, 14]}} \ &\purple{\text{[0.011, 0.098, 0.239, 0.305, 0.267, 0.066, 0.014]}} \end{aligned}

C’est-à-dire qu’il y a donc :

  • 1111 billes qui ont fini leur course dans le réservoir 00, soit une fréquence de 0,0110,011 ;
  • 9898 billes dans le réservoir 11, soit une fréquence de 0,0980,098 ;
  • 239239 billes dans le réservoir 22, soit une fréquence de 0,2390,239 ;
  • et cætera.

Conclusion

Appliquez cette fonction Python à l’exemple de la première partie : la planche de Galton modélisée dispose de 44 rangées de clous.
Simulez un lâcher de 10000001\,000\,000 de billes (laissez tourner patiemment l’algorithme, ça peut prendre un peu de temps… mais pas autant que si vous le faisiez manuellement !). Puis comparez les résultats avec la loi de probabilité donnée dans la partie précédente.

  • Quelle loi fondamentale des probabilités cela vous évoque-t-il ?