Cómo generar un punto aleatorio dentro de un círculo de radio R :
r = R * sqrt(random())
theta = random() * 2 * PI
(Suponiendo que random()
da un valor entre 0 y 1 de manera uniforme)
Si desea convertir esto a coordenadas cartesianas, puede hacer
x = centerX + r * cos(theta)
y = centerY + r * sin(theta)
¿Por qué sqrt(random())
?
Veamos las matemáticas que conducen a sqrt(random())
. Supongamos por simplicidad que estamos trabajando con el círculo unitario, es decir, R = 1.
La distancia promedio entre puntos debe ser la misma independientemente de cuán lejos del centro miremos. Esto significa, por ejemplo, que mirando el perímetro de un círculo con circunferencia 2 deberíamos encontrar el doble de puntos que el número de puntos en el perímetro de un círculo con circunferencia 1.
Como la circunferencia de un círculo (2π r ) crece linealmente con r , se deduce que el número de puntos aleatorios debería crecer linealmente con r . En otras palabras, la función de densidad de probabilidad deseada (PDF) crece linealmente. Como un PDF debe tener un área igual a 1 y el radio máximo es 1, tenemos
Entonces sabemos cómo debería ser la densidad deseada de nuestros valores aleatorios. Ahora: ¿Cómo generamos un valor aleatorio cuando todo lo que tenemos es un valor aleatorio uniforme entre 0 y 1?
Usamos un truco llamado muestreo de transformación inversa
- Desde el PDF, cree la función de distribución acumulativa (CDF)
- Refleje esto a lo largo de y = x
- Aplique la función resultante a un valor uniforme entre 0 y 1.
¿Suena complicado? Permítanme insertar una cita en bloque con una pequeña pista lateral que transmite la intuición:
Supongamos que queremos generar un punto aleatorio con la siguiente distribución:
Es decir
- 1/5 de los puntos uniformemente entre 1 y 2, y
- 4/5 de los puntos uniformemente entre 2 y 3.
El CDF es, como su nombre indica, la versión acumulativa del PDF. Intuitivamente: mientras PDF ( x ) describe el número de valores aleatorios en x , CDF ( x ) describe el número de valores aleatorios menores que x .
En este caso, el CDF se vería así:
Para ver cómo esto es útil, imagine que disparamos balas de izquierda a derecha a alturas distribuidas uniformemente. Cuando las balas golpean la línea, caen al suelo:
¡Vea cómo la densidad de las balas en el suelo corresponde a nuestra distribución deseada! ¡Casi estámos allí!
El problema es que para esta función, el eje y es la salida y el eje x es la entrada . ¡Solo podemos "disparar balas desde el suelo hacia arriba"! ¡Necesitamos la función inversa!
Es por eso que reflejamos todo el asunto; x se convierte en y e y se convierte en x :
Llamamos a esto CDF -1 . Para obtener valores de acuerdo con la distribución deseada, usamos CDF -1 (random ()).
... entonces, volviendo a generar valores de radio aleatorios donde nuestro PDF es igual a 2 x .
Paso 1: Cree el CDF:
dado que estamos trabajando con reales, el CDF se expresa como la integral del PDF.
CDF ( x ) = ∫ 2 x = x 2
Paso 2: Descarga el CDF a lo largo de y = x :
Matemáticamente, esto se reduce a intercambiar x e y resolver por y :
CDF : y = x 2
Intercambio: x = y 2
Resolver: y = √ x
CDF -1 : y = √ x
Paso 3: aplique la función resultante a un valor uniforme entre 0 y 1
CDF -1 (aleatorio ()) = √ aleatorio ()
Que es lo que nos propusimos derivar :-)