2010-08-18 19 views
14

Quiero generar números aleatorios según algunas distribuciones. ¿Cómo puedo hacer esto?Generar números aleatorios según las distribuciones

+2

Dejando de lado el hecho de que las computadoras solo generan números pseudoaleatorios, seguramente si se generan a una distribución conocida, entonces no son aleatorios. ¿Para qué distribuciones busca generar datos de muestra? – Lazarus

+0

La manera más fácil es encontrar una biblioteca que lo haga. ¿Tienes algún lenguaje en particular en mente? –

+0

Si usa Java, puede probar la biblioteca [Uncommons Maths by Dan Dyer] (http://maths.uncommons.org/) (* observe el comentario anterior *) que proporciona generadores de números aleatorios, distribuciones de probabilidad, combinatoria y estadísticas . – hengxin

Respuesta

15

El generador de números aleatorios estándar que tiene (rand() en C después de una transformación simple, equivalentes en muchos idiomas) es una aproximación bastante buena para una distribución uniforme en el rango [0,1]. Si eso es lo que necesitas, listo. También es trivial convertir eso a un número aleatorio generado en un rango entero algo mayor.

La conversión de una distribución uniforme a una distribución normal tiene already been covered on SO, como ha ido al Exponential distribution.

[EDIT]: Para la triangular distribution, la conversión de una variable uniforme es relativamente simple (en algo parecido a C):

double triangular(double a,double b,double c) { 
    double U = rand()/(double) RAND_MAX; 
    double F = (c - a)/(b - a); 
    if (U <= F) 
     return a + sqrt(U * (b - a) * (c - a)); 
    else 
     return b - sqrt((1 - U) * (b - a) * (b - c)); 
} 

eso es sólo la conversión de la fórmula dada en la página de Wikipedia. Si quieres a los demás, ese es el lugar para empezar a buscar; en general, usa la variable uniforme para elegir un punto en el eje vertical del cumulative density function de la distribución que desea (suponiendo que sea continuo) e invierta el CDF para obtener el valor aleatorio con la distribución deseada.

+0

no solo necesito tener algunos números que sean exponenciales, normales, triangulares ... etc. El analizador de entrada de Rockwell Arena hace esto, pero no sé cómo usarlo. –

+0

+1 Agradezco este pseudocódigo de C, porque estaba mirando el artículo de wikipedia sobre distribución triangular, y no pude encontrar la manera de convertirlo en código. Una corrección: rand() devuelve un número entero de 0 a RAND_MAX, por lo que creo que quiere 'U = ((double) rand())/RAND_MAX'. De lo contrario, su sqrt ((1 - U) ...) saldrá imaginario. – LarsH

+0

@LarsH: ¡Maldición! Olvidé que C es extraño de esa manera. Gracias por la corrección. –

3

Depende en realidad de la distribución. La forma más general es la siguiente. Deje P (X) la probabilidad de que el número aleatorio generado de acuerdo con su distribución sea menor que X.

Usted comienza con la generación de X aleatorio uniforme entre cero y uno. Después de eso, encuentras Y tal que P (Y) = X y la salida Y. Podrías encontrar tal Y usando la búsqueda binaria (ya que P (X) es una función creciente de X).

Esto no es muy eficiente, pero funciona para las distribuciones donde P (X) podría ser calculado de manera eficiente.

9

La forma correcta de hacer esto es descomponer la distribución en n-1 distribuciones binarias. Esto es, si usted tiene una distribución de la siguiente manera:

A: 0.05 
B: 0.10 
C: 0.10 
D: 0.20 
E: 0.55 

Usted transformarla en 4 distribuciones binarias:

1. A/E: 0.20/0.80 
2. B/E: 0.40/0.60 
3. C/E: 0.40/0.60 
4. D/E: 0.80/0.20 

Seleccionar uniformemente desde la N-1 distribuciones, y luego selecciona el primer o segundo símbolo basado en la probabilidad si cada uno en la distribución binaria.

Code for this is here

+0

Supones que la distribución es discreta. – pjs

+0

Estoy seguro, que es el caso típico en la programación (por ejemplo, tablas de transición de probabilidad, modelos de markov ocultos, etc.). Pero si nota que el método es * tiempo constante *. Esto significa que no hay penalización por el rendimiento en el tiempo para generar enormes distribuciones. Por lo tanto, para una distribución continua, podría incluirla en tantos contenedores como necesite para obtener una aproximación lo suficientemente buena y usar mi método. –

+1

Las RVs discretas pueden ser más comunes en el tipo de programación que usted hace, pero muchos de nosotros necesitamos distribuciones gaussianas, exponenciales, triangulares, log-normales, beta, gamma, Weibull, etc. para nuestro trabajo. Incluso con distribuciones discretas, no funcionan para rangos infinitos (Poisson, geométrico). Las tablas de alias generan valores en tiempo constante, pero también lo hacen la mayoría de las inversiones o composiciones continuas. Mientras tanto, la aproximación de las distribuciones continuas con tablas requiere una configuración y un almacenamiento masivos que no son necesarios con enfoques computacionales. Las tablas de alias son adorables cuando corresponde, pero no son una solución general. – pjs

0

Puede convertir de contenedores discretos flotar/doble con interpolación. Simple lineal funciona bien. Si su memoria de tabla está restringida, se pueden usar otros métodos de interpolación. -jlp

Cuestiones relacionadas