Come generare un punto casuale all'interno di un cerchio di raggio R :
r = R * sqrt(random())
theta = random() * 2 * PI
(Supponendo che random()
dia un valore tra 0 e 1 uniformemente)
Se vuoi convertirlo in coordinate cartesiane, puoi farlo
x = centerX + r * cos(theta)
y = centerY + r * sin(theta)
Perché sqrt(random())
?
Diamo un'occhiata alla matematica che porta a sqrt(random())
. Supponiamo per semplicità che stiamo lavorando con il cerchio unitario, cioè R = 1.
La distanza media tra i punti dovrebbe essere la stessa indipendentemente da quanto guardiamo dal centro. Ciò significa, ad esempio, che osservando il perimetro di un cerchio con circonferenza 2 dovremmo trovare il doppio dei punti rispetto al numero di punti sul perimetro di un cerchio con circonferenza 1.
Poiché la circonferenza di un cerchio (2π r ) cresce linearmente con r , ne consegue che il numero di punti casuali dovrebbe crescere linearmente con r . In altre parole, la funzione di densità di probabilità desiderata (PDF) cresce in modo lineare. Poiché un PDF dovrebbe avere un'area uguale a 1 e il raggio massimo è 1, abbiamo
Quindi sappiamo come dovrebbe apparire la densità desiderata dei nostri valori casuali. Ora: come possiamo generare un valore così casuale quando tutto ciò che abbiamo è un valore casuale uniforme tra 0 e 1?
Usiamo un trucco chiamato campionamento di trasformazioni inverse
- Dal PDF, creare la funzione di distribuzione cumulativa (CDF)
- Specchia questo lungo y = x
- Applicare la funzione risultante su un valore uniforme compreso tra 0 e 1.
Sembra complicato? Permettetemi di inserire una blockquote con un piccolo binario laterale che trasmetta l'intuizione:
Supponiamo di voler generare un punto casuale con la seguente distribuzione:
Questo è
- 1/5 dei punti uniformemente tra 1 e 2, e
- 4/5 dei punti uniformemente tra 2 e 3.
Il CDF è, come suggerisce il nome, la versione cumulativa del PDF. Intuitivamente: mentre PDF ( x ) descrive il numero di valori casuali in x , CDF ( x ) descrive il numero di valori casuali inferiore a x .
In questo caso il CDF sarebbe simile a:
Per vedere come questo sia utile, immagina di sparare proiettili da sinistra a destra ad altezze uniformemente distribuite. Quando i proiettili colpiscono la linea, cadono a terra:
Guarda come la densità dei proiettili sul terreno corrisponde alla nostra distribuzione desiderata! Ci siamo quasi!
Il problema è che per questa funzione, l' asse y è l' output e l' asse x è l' input . Possiamo solo "sparare proiettili da terra verso l'alto"! Abbiamo bisogno della funzione inversa!
Questo è il motivo per cui rispecchiamo tutto; x diventa y e y diventa x :
Questo CDF viene chiamato -1 . Per ottenere valori in base alla distribuzione desiderata, utilizziamo CDF -1 (random ()).
... quindi, tornando a generare valori di raggio casuali in cui il nostro PDF è uguale a 2 x .
Passaggio 1: creare il CDF:
poiché stiamo lavorando con reals, il CDF è espresso come integrale del PDF.
CDF ( x ) = ∫ 2 x = x 2
Passaggio 2: eseguire il mirroring del CDF lungo y = x :
Matematicamente questo si riduce a scambiare x e y e risolvendo per y :
CDF : y = x 2
Swap: x = y 2
Risolvi: y = √ x
CDF -1 : y = √ x
Passaggio 3: applicare la funzione risultante a un valore uniforme compreso tra 0 e 1
CDF -1 (random ()) = √random ()
Questo è ciò che abbiamo deciso di derivare :-)