C++ 如何生成泊松过程? 原始问题:

C++ 如何生成泊松过程? 原始问题:,c++,random,poisson,stochastic-process,C++,Random,Poisson,Stochastic Process,我想生成一个泊松过程。如果到达时间t的数量是N(t),并且我有一个参数为λ的泊松分布,我如何生成N(t)?在C++中如何做到这一点? 澄清: 我最初希望使用泊松分布生成流程。但是,我对我需要的过程参数感到困惑;我想我可以使用N(t),但这告诉我在区间(0,t)上发生了多少到达,这不是我想要的。因此,我想我可以使用N(t2)-N(t1)来获得区间[t1,t2]上到达的数量。因为N(t)~Poisson(txλ),我可以使用Poisson(t2xλ)-Poisson(t1 xλ)但我不希望在一段时间

我想生成一个泊松过程。如果到达时间t的数量是N(t),并且我有一个参数为λ的泊松分布,我如何生成N(t)?在C++中如何做到这一点?

澄清: 我最初希望使用泊松分布生成流程。但是,我对我需要的过程参数感到困惑;我想我可以使用N(t),但这告诉我在区间(0,t)上发生了多少到达,这不是我想要的。因此,我想我可以使用N(t2)-N(t1)来获得区间[t1,t2]上到达的数量。因为N(t)~Poisson(txλ),我可以使用Poisson(t2xλ)-Poisson(t1 xλ)但我不希望在一段时间内到达的人数

相反,我希望生成到达发生的明确时间


我可以通过使间隔[t2,t1]足够小,使每个间隔只有一个到达点(出现为| t2-t1 |->0)来实现这一点。

为了从分布中选取样本,需要计算逆累积分布函数(CDF)。首先在真实间隔[0,1]上均匀地选取一个随机数,然后取该值的逆CDF。

我会非常小心地使用逆CDF并通过它泵送一个均匀的随机数。这里的问题是,逆CDF通常在数值上是不稳定的,或者产生它的函数可能会在区间的末端产生不希望的波动。因此,我建议类似于“C中的数字配方”中使用的拒绝方法。参见NRC第7.3章中给出的poidev函数:

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


如果你想要一个泊松过程,到达之间的时间是指数分布的,可以使用反向CDF方法生成指数值:-k*log(u),其中u是一个均匀的随机变量,k是指数的平均值。

如果你使用python,你可以使用random.exponentiate(rate)要以每个时间间隔的速率事件生成到达时间,如果有一个带有速率参数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)
import random
t= 0
for i in range(1,10):
   t+= random.expovariate(15)
   print t
请注意,这将生成*inter*到达时间。如果需要到达时间,则必须继续向前移动时间变量,如下所示:

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

这里的讨论详细介绍了如何使用反向采样生成到达间隔,这通常是人们在游戏中想要做的事情


在python中,您可以尝试以下代码

如果您想在60秒内生成20个随机读数,即(20是λ)


通过泊松过程生成到达时间并不意味着使用泊松分布,而是基于泊松到达率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;  
  }

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

参考:


谢谢-我的想法就是这样,但我觉得很奇怪,因为cdf生成N(t)而不是t。而且,我不知道从N(t)采样以获得泊松过程的正确方法。如果我没有从cdf中均匀采样(它仍然是泊松过程)会发生什么转换一个Poisson的CDF并不容易或有效。对于一种更有效的方法,请参见Corwin的链接或查看如何使用C++ Tr1的答案。链接是一个空白PDF。我有C++版本(V3我相信)。它甚至不包括泊松偏差。但是,我的理解是,偏差是分布的样本,这会让我从哪里开始。这不是泊松分布的链接,不是泊松过程吗?很好。如果你想要泊松过程,到达之间的时间是指数分布的,指数值es可以通过反向CDF方法生成:-k*log(u),其中u是均匀随机变量,k是指数的平均值。顺便说一下,不是平均值(刻度)指数分布的
1/k
,而不是
k
?指数分布的参数化有两种不同的约定。在计算
log(rand())
时,请确保不要使用0的对数。常见的技巧是将
log(1.0-rand())
改为
rand())
通常返回一个小于1的数字。请注意,这将生成到达间隔时间。这是我看到的最好的解释