C++ 如何生成泊松过程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1155539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I generate a Poisson Process?
提问by bias
Original Question:
原问题:
I want to generate a Poisson process. If the number of arrivals by time tis N(t)and I have a Poisson distribution with parameter λhow do I generate N(t)? How would I do this in C++?
我想生成泊松过程。如果时间t的到达次数是N(t)并且我有参数为λ的泊松分布,我如何生成N(t)?我将如何在 C++ 中做到这一点?
Clarification:
澄清:
I originally wanted to generate the process using a Poisson distribution. But, I was confused about what parameter from the process I needed; I thought I could use N(t)but that tells me how many arrivals have occurred on the interval (0,t]which wasn't what I wanted. So, then I thought I could use N(t2)-N(t1)to get the number of arrivals on the interval [t1,t2]. Since N(t)~Poisson(t x λ)I could use Poisson(t2 x λ)-Poisson(t1 x λ)but I don't want the number of arrivals in an interval.
我最初想使用泊松分布生成过程。但是,我对我需要的过程中的哪些参数感到困惑;我以为我可以使用N(t)但这告诉我在间隔(0,t]上发生了多少次到达,这不是我想要的。所以,然后我想我可以使用N(t2)-N(t1 )来获得间隔[t1,t2]上的到达次数。由于N(t)~Poisson(tx λ)我可以使用Poisson(t2 x λ)-Poisson(t1 x λ)但我不想要间隔内的到达次数。
Rather, I want to generate the explicit times that arrivals occur at.
相反,我想生成到达发生的明确时间。
I could do this by making the interval [t2,t1]sufficiently small so that each interval has only one arrival (which occurs as |t2-t1| -> 0).
我可以通过使间隔[t2,t1]足够小来做到这一点,以便每个间隔只有一个到达(发生为|t2-t1| -> 0)。
采纳答案by John D. Cook
Here's sample code for generating Poisson samples using C++ TR1.
这是使用C++ TR1生成泊松样本的示例代码。
If you want a Poisson process, times between arrivals are exponentially distributed, and exponential values can be generated trivially with the inverse CDF method: -k*log(u) where u is a uniform random variable and k is the mean of the exponential.
如果您想要泊松过程,到达之间的时间呈指数分布,并且可以使用逆 CDF 方法轻松生成指数值: -k*log(u) 其中 u 是均匀随机变量,k 是指数的平均值。
回答by Chris Marshall
If you have a Poisson process with rate parameter L (meaning that, long term, there are L arrivals per second), then the inter-arrival times are exponentially distributed with mean 1/L. So the PDF is f(t) = -L*exp(-Lt), and the CDF is F(t) = Prob(T < t) = 1 - exp(-Lt). So your problem changes to: how to I generate a random number t with distribution F(t) = 1 - \exp(-Lt)?
如果您有一个速率参数为 L 的泊松过程(这意味着,从长远来看,每秒有 L 次到达),那么到达间隔时间呈指数分布,平均为 1/L。所以 PDF 是 f(t) = -L*exp(-Lt),CDF 是 F(t) = Prob(T < t) = 1 - exp(-Lt)。所以你的问题变成了:如何生成一个分布为 F(t) = 1 - \exp(-Lt) 的随机数 t?
Assuming the language you are using has a function (let's call it rand()
) to generate random numbers uniformly distributed between 0 and 1, the inverse CDF technique reduces to calculating:
假设您使用的语言有一个函数(我们称之为rand()
)来生成均匀分布在 0 和 1 之间的随机数,逆 CDF 技术简化为计算:
-log(rand()) / L
As python provides a function to generate exponentially distributed random numbers, you could simulate the first 10 events in a poisson process with an averate rate of 15 arrivals per second like this:
由于 python 提供了一个函数来生成指数分布的随机数,您可以模拟泊松过程中的前 10 个事件,平均速率为每秒 15 次,如下所示:
import random
for i in range(1,10):
print random.expovariate(15)
Note that that would generate the *inter*arrival times. If you wanted the arrival times, you would have to keep moving a time variable forward like this:
请注意,这将生成 *inter*arrival 时间。如果您想要到达时间,则必须像这样继续向前移动时间变量:
import random
t= 0
for i in range(1,10):
t+= random.expovariate(15)
print t
回答by John D. Cook
I would be very careful about using the inverse CDF and pumping a uniform random number through it. The problem here is that often the inverse CDF is numerically unstable or the functions to produce it can give undesirable fluctuations near the ends of the interval. For that reason I would recommend something like the rejection method used in "Numerical Recipes in C". See the poidev function given in ch 7.3 of NRC: http://www.nrbook.com/a/bookcpdf/c7-3.pdf
我会非常小心地使用逆 CDF 并通过它抽取一个统一的随机数。这里的问题是,逆 CDF 通常在数值上不稳定,或者产生它的函数可能会在区间末端附近产生不希望的波动。出于这个原因,我会推荐类似“C 中的数字食谱”中使用的拒绝方法。参见 NRC ch 7.3 中给出的 poidev 函数:http://www.nrbook.com/a/bookcpdf/c7-3.pdf
回答by Steve Brown
If you are using python, you can use random.expovariate(rate) to generate arrival times at rate events per time interval
如果您使用的是 python,则可以使用 random.expovariate(rate) 以每个时间间隔的速率事件生成到达时间
回答by Adam Rosenfield
In order to pick a sample from a distribution, you need to compute the inverse cumulative distribution function (CDF). You first pick a random number uniformly on the real interval [0, 1], and then take the inverse CDF of that value.
为了从分布中选取样本,您需要计算逆累积分布函数 (CDF)。您首先在实数区间 [0, 1] 上均匀地选取一个随机数,然后取该值的逆 CDF。
回答by jdbertron
The discussion here has all the details about using inverse sampling to generate inter-arrivals, which is usually what people want to do for games.
这里的讨论包含有关使用逆采样生成到达间隔的所有细节,这通常是人们想要为游戏做的事情。
回答by josepainumkal
In python, you can try below code.
在python中,您可以尝试以下代码。
If you want to generate 20 random readings in 60 seconds. ie (20 is the lambda)
如果要在 60 秒内生成 20 个随机读数。即(20 是 lambda)
def poisson_job_generator():
rateParameter = 1.0/float(60/20)
while True:
sl = random.expovariate(rateParameter)
回答by Mohammed Ziad
Generating arrival times via Poisson Process does not mean using a Poisson distribution. It is done by creating an exponential distribution based on the Poisson arrival rate lamda.
通过泊松过程生成到达时间并不意味着使用泊松分布。它是通过基于泊松到达率 lamda 创建指数分布来完成的。
In short, you need to generate an exponential distribution with an average = 1/lamda, see the following example:
简而言之,您需要生成一个平均值 = 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;
}
}
The result of running this code:
运行这段代码的结果:
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
so, based on your experiment you can either use: newArrivalTime or sumArrivalTimes.
因此,根据您的实验,您可以使用:newArrivalTime 或 sumArrivalTimes。
ref: http://www.math.wsu.edu/faculty/genz/416/lect/l05-45.pdf
参考:http: //www.math.wsu.edu/faculty/genz/416/lect/l05-45.pdf