如何生成泊松过程?

时间:2009-07-20 19:45:35

标签: c++ random poisson stochastic-process

原始问题:

我想生成一个泊松过程。如果按时间 t 的到达次数是 N(t)并且我有一个带参数λ的泊松分布,我该如何生成 N(t)的?我怎么用C ++做这个?

澄清:

我原本想用泊松分布生成过程。但是,我对我需要的过程中的参数感到困惑;我以为我可以使用 N(t),但是它告诉我在(0,t)的间隔发生了多少到达,这不是我想要的。所以,然后我想我可以使用 N(t2)-N(t1)来获得区间 [t1,t2] 的到达次数。由于 N( t)〜泊松(txλ)我可以使用 Poisson(t2xλ)-Poisson(t1xλ),但我不想在一个区间内到达的数量。 / p>

相反,我想生成到达时出现的显式时间。

我可以通过使间隔 [t2,t1] 足够小来做到这一点,这样每个间隔只有一个到达(发生在 | t2-t1 | - > 0 < / em>的)。

8 个答案:

答案 0 :(得分:22)

如果你有一个带速率参数L的泊松过程(意味着,长期,每秒有L个到达),那么到达间隔时间是指数分布的,均值为1 / L.因此PDF是f(t)= -L * exp(-Lt),并且CDF是F(t)= Prob(T

假设您使用的语言具有一个函数(让我们称之为rand())来生成均匀分布在0和1之间的随机数,则逆CDF技术会减少到计算:

-log(rand()) / L

由于python提供了一个生成指数分布随机数的函数,你可以模拟泊松过程中的前10个事件,每秒15个到达的平均速率如下:

import random
for i in range(1,10):
   print random.expovariate(15)

请注意,这会产生* inter *到达时间。如果你想要到达时间,你必须继续向前移动一个时间变量:

import random
t= 0
for i in range(1,10):
   t+= random.expovariate(15)
   print t

答案 1 :(得分:5)

以下是使用C++ TR1生成泊松样本的示例代码。

如果你想要Poisson 过程,到达之间的时间是指数分布的,并且可以用逆CDF方法简单地生成指数值:-k * log(u)其中u是一个随机的随机数变量和k是指数的平均值。

答案 2 :(得分:3)

我会非常小心地使用逆CDF并通过它抽一个均匀的随机数。这里的问题是逆CDF通常在数值上不稳定,或者产生它的函数可能在间隔的末端附近产生不希望的波动。出于这个原因,我会推荐像“C中的数字食谱”中使用的拒绝方法。参见NRC第7.3节中给出的poidev函数:http://www.nrbook.com/a/bookcpdf/c7-3.pdf

答案 3 :(得分:1)

要从分布中选取样本,您需要计算逆累积分布函数(CDF)。首先在实际区间[0,1]上统一选取一个随机数,然后取该值的逆CDF。

答案 4 :(得分:1)

如果你使用python,你可以使用random.expovariate(rate)来生成每个时间间隔的速率事件的到达时间

答案 5 :(得分:0)

此处的讨论包含使用反向采样生成到达间隔的所有细节,这通常是人们想要为游戏做的事情。

https://stackoverflow.com/a/15307412/1650437

答案 6 :(得分:0)

在python中,你可以尝试下面的代码。

如果要在60秒内生成20个随机读数。即(20是lambda)

 def poisson_job_generator():
    rateParameter = 1.0/float(60/20) 
    while True:
        sl = random.expovariate(rateParameter)

答案 7 :(得分:0)

通过泊松过程生成到达时间并不意味着使用泊松分布。这是通过基于泊松到达率lamda创建指数分布来完成的。

简而言之,您需要生成一个平均值= 1 / lamda的指数分布,请参阅以下示例:

#include <iostream>
#include <iterator>
#include <random>

int
main ()
{
 // seed the RNG
 std::random_device rd; // uniformly-distributed integer random number generator
 std::mt19937 rng (rd ()); // mt19937: Pseudo-random number generation

 double averageArrival = 15;
 double lamda = 1 / averageArrival;
 std::exponential_distribution<double> exp (lamda);

double sumArrivalTimes=0;
double newArrivalTime;


 for (int i = 0; i < 10; ++i)
  {
   newArrivalTime=  exp.operator() (rng); // generates the next random number in the distribution 
   sumArrivalTimes  = sumArrivalTimes + newArrivalTime;  
   std::cout << "newArrivalTime:  " << newArrivalTime  << "    ,sumArrivalTimes:  " << sumArrivalTimes << std::endl;  
  }

}

运行此代码的结果:

newArrivalTime:  21.6419    ,sumArrivalTimes:  21.6419
newArrivalTime:  1.64205    ,sumArrivalTimes:  23.2839
newArrivalTime:  8.35292    ,sumArrivalTimes:  31.6368
newArrivalTime:  1.82962    ,sumArrivalTimes:  33.4665
newArrivalTime:  34.7628    ,sumArrivalTimes:  68.2292
newArrivalTime:  26.0752    ,sumArrivalTimes:  94.3045
newArrivalTime:  63.4728    ,sumArrivalTimes:  157.777
newArrivalTime:  3.22149    ,sumArrivalTimes:  160.999
newArrivalTime:  1.64637    ,sumArrivalTimes:  162.645
newArrivalTime:  13.8235    ,sumArrivalTimes:  176.469

因此,根据您的实验,您可以使用:newArrivalTime或sumArrivalTimes。

  

参考:http://www.math.wsu.edu/faculty/genz/416/lect/l05-45.pdf