Número aleatorio dentro de un rango basado en una distribución normal


Quiero generar números aleatorios con un rango (n a m, por ejemplo, 100 a 150), pero en lugar de puramente aleatorio quiero que los resultados se basen en la distribución normal.

Con esto quiero decir que en general quiero que los números "agrupados" alrededor de 125.

He encontrado este paquete de números aleatorios que parece tener mucho de lo que necesito: http://codeproject.com/KB/recipes/Random.aspx

Es compatible con una variedad de generadores aleatorios (incluyen mersiene twister) y puede aplicar el generador a una distribución.

Pero estoy confundido, si uso un generador de distribución normal los números aleatorios son de aproximadamente -6 a +8 (aparentemente el rango verdadero es float.min a flotar.max).

¿Cómo escalar eso a mi rango requerido?

Author: Peter O., 2010-05-02

6 answers

Una distribución normal estándar tiene media 0 y desviación estándar de 1; si desea hacer una distribución con media m y desviación s, simplemente multiplique por s y luego agregue m. Dado que la distribución normal es teóricamente infinita, no puede tener un límite rígido en su rango, por ejemplo (100 a 150) sin rechazar explícitamente los números que caen fuera de él, pero con una elección adecuada de desviación, puede estar seguro de que (por ejemplo) el 99% de sus números estarán dentro del rango.

Alrededor del 99,7% de una población se encuentra dentro de +/- 3 desviaciones estándar, por lo que si elige la suya para ser aproximadamente (25/3), debería funcionar bien.

Entonces quieres algo como: (normal * 8.333) + 125

 26
Author: tzaman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-01 23:50:41

Por el bien del interés, es bastante sencillo generar números aleatorios distribuidos normalmente a partir de un RNG uniforme (aunque debe hacerse en pares):

Random rng = new Random();
double r = Math.Sqrt(-2 * Math.Log(rng.NextDouble()));
double θ = 2 * Math.Pi * rng.NextDouble();
double x = r * Math.Cos(θ);
double y = r * Math.Sin(θ);

x y y ahora contienen dos números aleatorios independientes, normalmente distribuidos con media 0 y varianza 1. Puede escalarlos y traducirlos según sea necesario para obtener el rango que desee (como explica interjay).


Explicación:

Este método se llama Box-Muller transform . Utiliza la propiedad de la unidad bidimensional gaussiana de que el valor de densidad en sí, p = exp(-r^2/2), se distribuye uniformemente entre 0 y 1 (constante de normalización eliminada por simplicidad).

Dado que puede generar dicho valor fácilmente usando un RNG uniforme, termina con un contorno circular de radio r = sqrt(-2 * log(p)). A continuación, puede generar una segunda variación aleatoria uniforme entre 0 y 2*pi para obtener un ángulo θ que define un punto único en su circular contorno. Finalmente, puede generar dos variables aleatorias normales i.i.d. transformándose de coordenadas polares (r, θ) de nuevo en coordenadas cartesianas (x, y).

Esta propiedad – que p está uniformemente distribuida – no se aplica a otras dimensionalidades, por lo que debe generar exactamente dos variables normales a la vez.

 14
Author: Will Vousden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-19 17:55:06

La respuesta de Tzaman es correcta, pero cuando se usa la biblioteca enlazada hay una forma más simple que realizar el cálculo usted mismo: El objeto NormalDistribution tiene propiedades de escritura Mu (que significa la media) y Sigma (desviación estándar). Así que yendo por los números de tzaman, pon Mu a 125 y Sigma a 8.333.

 4
Author: interjay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-01 23:55:39

Esto puede ser demasiado simplista para sus necesidades, pero una forma rápida y barata de obtener un número aleatorio con una distribución que se pondera hacia el centro es simplemente agregar 2 (o más) números aleatorios.

Piensa en cuando lanzas dos dados de 6 lados y los añades. La suma es más a menudo 7, luego 6 y 8, luego 5 y 9, etc. y sólo raramente 2 o 12.

 2
Author: dkamins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-01 23:44:08

Aquí hay otro algoritmo que no necesita calcular Sin/Cos, ni necesita saber Pi. No me preguntes sobre el trasfondo teórico. Lo encontré en algún lugar una vez y es lo que he estado usando desde entonces. Sospecho que es algún tipo de normalización de la misma transformación Box-Muller que menciona @Will Vousden. También produce resultados en pares.

El ejemplo es VBScript; bastante fácil de convertir a cualquier otro lenguaje.

Sub calcRandomGauss (byref y1, byref y2)
    Dim x1, x2, w
    Do
        x1 = 2.0 * Rnd() - 1.0
        x2 = 2.0 * Rnd() - 1.0
        w = x1 * x1 + x2 * x2
    Loop While w >= 1.0 Or w = 0  'edited this line, thanks Richard

    w = Sqr((-2.0 * Log(w)) / w )
    y1 = x1 * w
    y2 = x2 * w
End Sub
 0
Author: mgr326639,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-27 22:16:50

Un enfoque diferente para este problema utiliza la distribución beta (que tiene un rango duro, a diferencia de la distribución normal) e implica elegir los parámetros apropiados de modo que la distribución tenga la media y la desviación estándar dadas (raíz cuadrada de varianza). Ver esta pregunta.

 0
Author: Peter O.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-30 23:41:37