1 votos

Modelización de un proceso de Poisson con 10000 eventos por minuto

Estoy tratando de modelar un sistema que genera eventos modelados por un proceso de Poisson.

Estoy utilizando el siguiente código ruby:

INTERVAL = 0.005
LAMBDA = 167.0
events = Hash.new(0)

def f(x, lambda)
  1 - Math.exp(-lambda * x)
end

random_gen = Random.new
start = Time.now.to_f

while Time.now.to_i - start < 60
  if random_gen.rand < f(INTERVAL, LAMBDA)
    bucket = (Time.now.to_f - start).round.to_i
    events[bucket] += 1
  end

  sleep(INTERVAL)
end

Estoy tratando de generar unos 10000 eventos por minuto, o 167 eventos/segundo, por lo que estoy utilizando $\lambda = 167$ .

Estoy utilizando la función f como $1 - e^{(-\lambda x)}$ donde $x$ es el intervalo en el que duermo, estoy utilizando esta función para que el tiempo de interllegada de los eventos siga una distribución exponencial.

Sin embargo, no estoy obteniendo los resultados esperados, este código genera unos 7194 eventos por minuto, con una media de unos 117 eventos por segundo. Yo esperaría que este código generara 10000 eventos por minuto con una media de unos 167 eventos por segundo.

¿Qué estoy haciendo mal?

Gracias por su ayuda.

ACTUALIZACIÓN Se ha corregido un error tipográfico en el tiempo de muestreo y se ha añadido random_gen y start definiciones

3voto

matt Puntos 11

¿Cómo se consigue más de $20$ eventos por segundo si está durmiendo durante $1/20$ de segundo entre comprobaciones? En caso de que se utilicen intervalos de longitud $0.005$ entonces podrías ver hasta $200$ eventos, pero estás tirando cada evento después del primero en cada intervalo. Esto llevaría a una media de $200(1-\exp(-167/200)) = 113.225$ por segundo, con una distribución binomial en lugar de una distribución de Poisson. Es posible que vea un poco menos si realmente está muestreando con menos frecuencia que una vez cada $0.005$ segundos. Al menos deberías probar la frecuencia con la que se ejecuta tu bucle.

1voto

JMW.APRN Puntos 21

Sólo se llama f sólo a través de f(INTERVAL, LAMBDA) que es una constante igual a 0,9997636. Esto significa que pasará por el if bloquea casi siempre.

Se duerme un tiempo constante aproximadamente igual a $1/20^{th}$ segundo por lo que hará un poco menos de 20 while ciclos por segundo debido al tiempo de sobrecarga de las llamadas a las funciones. Así que deberías obtener alrededor de 17-19 eventos por segundo.

Eso responde a lo que está fallando. Ahora, para arreglarlo, necesitas hacer f y sleep dependen de su variable aleatoria. No soy experto en rubí, así que es difícil para mí decir, pero sugiero algo como:

def f()
   # Return an exponential waiting time
   - Math.log(random_gen.rand)
end

y

sleep(f()*0.006)

0voto

mat_geek Puntos 1367

Si se quiere generar eventos a partir de un proceso de Poisson generando tiempos de interllegada se elige X tal que $F(X)=U$ donde $U$ es uniforme en $U[0,1]$ y $F(X)=1-\exp(-\lambda X)$ . Por lo tanto, se establece $U=1-\exp(-\lambda X)$ o $1-U=\exp(-\lambda X)$ o $-\log(1-U)/\lambda =X$ . Generar $10000$ $X's$ de esta manera y luego contar cuántos $X's$ son inferiores a $60$ segundos. No creo que sea eso lo que hace tu código.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X