Tom Marx

Calculez PI avec la méthode de Monte Carlo

Le 16/03/2019 par Tom Marx

Calculez PI avec la méthode de Monte Carlo

Temps de lecture : environ 10 minutes

L'expérience de Monte Carlo

Les expériences de Monte Carlo sont des protocoles permettant d'approcher la valeur d'un nombre à l'aide de nombres aléatoires.
On peut se servir de ces méthodes pour approximer la valeur de PI. Voici le protocole :

Ici, on a lancé 2 fléchettes, une dans la cible (la bleue), et une en dehors (la rouge).
Maintenant, comment obtenir la valeur de PI grâce au nombre de fléchettes qui ont touché la cible et le nombre de fléchette total ?
D'abord voyons la formule de l'air du cercle et du carré :
`A_{"cerle"} = pi*r^2`
`A_{"carre"} = (2 * r)^2 = 4 * r^2`
En lançant un grand nombre de fléchettes, `N_{"cible"}/N_{"total"}` va tendre vers `A_{"cercle"} / A_{"carre"}`. Il faut maintenant extraire PI de cette relation :
`A_{"cercle"} / A_{"carre"} = (pi*r^2)/(4 * r^2) = pi / 4`
`N_{"cible"}/N_{"total"} = pi / 4`
`pi = 4 * N_{"cible"}/N_{"total"}`
On a désormais une relation qui nous permet de retrouver PI en fonction du nombres de fléchettes qui touchent la cible. On peut désormais créer une simulation.

Création d'une simulation en javascript

Le code est plutôt court et simple :

// Le nombre de fléchettes qui ont touché la cible, et le nombre total de fléchettes tirées
var inside = 0
var total = 0

function setup()
{
  // On crée le canvas de taille 500x500px
  // La fonction .parent() permet de placer le canvas dans la div avec l'id donnée
  createCanvas(500, 500).parent("content")

  background(200)

  // On dessine le cercle
  stroke(100)
  fill(0, 0, 0, 0)
  ellipse(width / 2, height / 2, width, height)
}

function draw()
{
  // A chaque frame, on tir 100 fléchettes
  for (var i = 0; i < 100; i++)
    random_point()

  // On met à jour notre approximation de PI grâce à la formule
  let pi_val = (inside / (total)) * 4
  // On affiche notre valeur arrondie à 4 chiffres après la virgule dans la console
  console.log(Math.rond(pi_val * 10000) / 10000)
}

// La fonction qui tire une fléchette
function random_point()
{
  // On choisi des coordonnées aléatoires sur le canvas
  let x = random(0, width)
  let y = random(0, height)

  // On regarde si la distance du point par rapport au centre du cercle est inférieur à son rayon --> on regarde si le point est dans le cercle on non
  if ( Math.pow((width / 2) - x, 2) + Math.pow((height / 2) - y, 2) < Math.pow(width / 2, 2) )
  {
    fill(23, 109, 169)
    inside += 1
  } else {
    fill(200, 100, 100)
  }
  total += 1
  noStroke()
  ellipse(x, y, 3, 3)
}