Comment générer un point aléatoire dans un cercle de rayon R :
r = R * sqrt(random())
theta = random() * 2 * PI
(En supposant random()
donne une valeur entre 0 et 1 uniformément)
Si vous souhaitez convertir cela en coordonnées cartésiennes, vous pouvez le faire
x = centerX + r * cos(theta)
y = centerY + r * sin(theta)
Pourquoi sqrt(random())
?
Regardons les mathématiques qui mènent à sqrt(random())
. Supposons pour plus de simplicité que nous travaillons avec le cercle unitaire, c'est-à-dire R = 1.
La distance moyenne entre les points doit être la même quelle que soit la distance du centre que nous regardons. Cela signifie par exemple, qu'en regardant sur le périmètre d'un cercle de circonférence 2, nous devrions trouver deux fois plus de points que le nombre de points sur le périmètre d'un cercle de circonférence 1.
Puisque la circonférence d'un cercle (2π r ) croît linéairement avec r , il s'ensuit que le nombre de points aléatoires devrait croître linéairement avec r . En d'autres termes, la fonction de densité de probabilité souhaitée (PDF) croît linéairement. Puisqu'un PDF doit avoir une aire égale à 1 et le rayon maximum est 1, nous avons
Nous savons donc à quoi devrait ressembler la densité souhaitée de nos valeurs aléatoires. Maintenant: comment générer une telle valeur aléatoire alors que tout ce que nous avons est une valeur aléatoire uniforme entre 0 et 1?
Nous utilisons une astuce appelée échantillonnage par transformée inverse
- A partir du PDF, créez la fonction de distribution cumulative (CDF)
- Miroir ceci le long de y = x
- Appliquez la fonction résultante à une valeur uniforme entre 0 et 1.
Cela semble compliqué? Permettez-moi d'insérer un blockquote avec une petite piste latérale qui transmet l'intuition:
Supposons que nous voulons générer un point aléatoire avec la distribution suivante:
C'est
- 1/5 des points uniformément entre 1 et 2, et
- 4/5 des points uniformément entre 2 et 3.
Le CDF est, comme son nom l'indique, la version cumulative du PDF. Intuitivement: alors que PDF ( x ) décrit le nombre de valeurs aléatoires à x , CDF ( x ) décrit le nombre de valeurs aléatoires inférieures à x .
Dans ce cas, le CDF ressemblerait à:
Pour voir comment cela est utile, imaginez que nous tirons des balles de gauche à droite à des hauteurs uniformément réparties. Lorsque les balles atteignent la ligne, elles tombent au sol:
Voyez comment la densité des balles au sol correspond à notre distribution souhaitée! Nous y sommes presque!
Le problème est que pour cette fonction, l' axe y est la sortie et l' axe x est l' entrée . Nous ne pouvons que "tirer des balles à partir du sol"! Nous avons besoin de la fonction inverse!
C'est pourquoi nous reflétons le tout; x devient y et y devient x :
Nous appelons cela CDF -1 . Pour obtenir des valeurs selon la distribution souhaitée, nous utilisons CDF -1 (random ()).
… Donc, revenons à la génération de valeurs de rayon aléatoires où notre PDF est égal à 2 x .
Étape 1: créer le CDF:
Puisque nous travaillons avec des réels, le CDF est exprimé comme l'intégrale du PDF.
CDF ( x ) = ∫ 2 x = x 2
Étape 2: miroir du CDF le long de y = x :
Mathématiquement, cela se résume à permuter x et y et à résoudre pour y :
CDF : y = x 2
Swap: x = y 2
Résoudre: y = √ x
CDF -1 : y = √ x
Étape 3: appliquez la fonction résultante à une valeur uniforme entre 0 et 1
CDF -1 (aléatoire ()) = √ aléatoire ()
C'est ce que nous avons décidé de tirer :-)