我想生成一个泊松过程。如果到时间t的到达次数是N(t)并且我有一个带参数λ的泊松分布,我该如何产生N(t)?我将如何在C ++中执行此操作?
我原本想用泊松分布生成过程。但是,我对我需要的过程中的参数感到困惑;我以为我可以使用N(t),但是它告诉我在间隔(0,t)上发生了多少到达,这不是我想要的。所以,我认为我可以使用N(t2)-N(t1) )获得区间[t1,t2]上的到达次数。由于N(t)〜泊松(txλ)我可以使用泊松(t2xλ)-Pisson(t1xλ),但我不希望一个区间内的到达人数。
相反,我想生成到达时出现的明确时间。
我可以通过使间隔[t2,t1]足够小以使每个间隔只有一个到达(发生为| t2-t1 | - > 0)来做到这一点。
这是使用C++ TR1生成泊松样本的示例代码。
如果你想要泊松过程,到达之间的时间是指数分布的,并且可以用逆CDF方法简单地生成指数值:-k * log(u)其中u是均匀随机变量,k是指数的平均值。
如果你有一个带速率参数L的泊松过程(意味着长期,每秒有L个到达),那么到达间隔时间是指数分布的,均值为1 / L.因此PDF是f(t)= -L * exp(-Lt),并且CDF是F(t)= Prob(T <t)= 1-exp(-Lt)。所以你的问题变成:如何生成一个随机数t,分布F(t)= 1 - \ exp(-Lt)?
假设你使用的语言有一个函数(我们称之为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
我会非常小心地使用逆CDF并通过它抽一个均匀的随机数。这里的问题是逆CDF通常在数值上不稳定,或者产生它的函数可能在间隔的末端附近产生不希望的波动。出于这个原因,我会推荐像“C中的数字食谱”中使用的拒绝方法。参见NRC第7.3节中给出的poidev函数:http://www.nrbook.com/a/bookcpdf/c7-3.pdf
要从分布中选取样本,您需要计算逆累积分布函数(CDF)。首先在实际区间[0,1]上统一选取一个随机数,然后取该值的逆CDF。
如果您使用的是python,则可以使用random.expovariate(rate)来生成每个时间间隔的速率事件的到达时间
这里的讨论包含了使用反向采样来生成到达间隔的所有细节,这通常是人们想要为游戏做的事情。
在python中,您可以尝试下面的代码。
如果要在60秒内生成20个随机读数。即(20是lambda)
def poisson_job_generator():
rateParameter = 1.0/float(60/20)
while True:
sl = random.expovariate(rateParameter)
通过泊松过程生成到达时间并不意味着使用泊松分布。这是通过基于泊松到达率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。
ref:http://www.math.wsu.edu/faculty/genz/416/lect/l05-45.pdf