通过泊松过程生成随机到达 C++

Generating random arrivals via Poisson process c++

有些地方我不明白。我使用 cpp 参考中给出的示例来生成数字:

const int nrolls = 10; // number of experiments

std::default_random_engine generator;
std::poisson_distribution<int> distribution(4.1);

for (int i=0; i<nrolls; ++i){
int number = distribution(generator);
cout<<number<<" "<<endl;
}

(原码:http://www.cplusplus.com/reference/random/poisson_distribution/

输出:2 3 1 4 3 4 4 3 2 3 等等... 首先这些数字是什么意思?我的意思是我必须对它们求和才能创造时间吗?例如: 2, (2+3)=5, (5+1)=6, (6+4)=10,...,等等..

其次,我真正的问题是,我需要生成网络数据包的随机到达和数据包的大小。我的意思是,当数据包到来时,如果数据包到来,数据包的大小是多少?我怎样才能做到这一点?我需要这样的东西: http://i.hizliresim.com/dWmaGX.png

[关于泊松分布的解释,可以帮助你更好地理解]

"Poisson distribution"的含义与"std::poisson_distribution()"的作用密切相关,但又不相同。

泊松分布是一种离散的概率分布。您可以计算概率,例如下一个时间段(例如一秒)没有数据包到达的概率为 0.002,一个数据包的概率为 0.075,两个数据包的概率为 0.15,三个数据包的概率为 0.20,依此类推,平均到达时间为4.(我使用的可能性值是样本(不是真实值)) 0包到无限包的概率总和总是变成1.0。

std::poisson_distribution() returns 每个周期的数据包数量,长期数据包的平均值等于平均值​​(代码中为 4.1),它们的分布是泊松分布。

您可以按照以下步骤计算。

  1. table的number_of_packet和概率。

  2. 取一个0到1之间的随机数

  3. 对table中的概率求和,直到和变得大于随机数。

  4. (用于求和的概率数)-2为值

示例:如果您得到 0.3 作为随机数。

无包到两个包的概率之和为0.002+0.075+0.15=0.227小于0.3。

无包到三个包的概率之和为0.002+0.075+0.15+0.20=0.427大于0.3

然后'two packets'用于下一个值。

这是 std::poisson_distribution() 中发生的情况的说明。

[直接回答你的 question:How 使数据包到达泊松分布]

为了便于理解,我假设一个周期是一秒。

outputs: 2 3 1 4 3 4 4 3 2 3 你得到的是每秒的包数, 第一秒两个数据包,第二秒三个数据包,第三秒一个数据包,依此类推。

您可以在那一秒均匀地放置数据包来到达。

[输出示例:2 3 1]

时间 0 秒 - 1 秒

两个数据包到达。将 1 秒除以 2(两个 0.5 秒周期),并将数据包放在中间。 => 第一个数据包放置在 0.25 秒,第二个数据包放置在 0.75 秒。

时间 1s - 2s

有数据包到达。将 1 秒除以 3,然后将数据包放在中间。 => 第一个数据包放置在 1.166 秒,第二个数据包在 1.5 秒,第三个数据包在 1.833。

...等等。

0.25, 0.75, 1.166, 1.5, 1.833 是你得到的'outputs: 2 3'前五个包的到达时间

===== 数据包的大小是另一个问题。

您应该确定用于数据包大小的分布。

我不认为泊松分布适合数据包大小table。

恐怕您通过泊松过程生成到达时间的方式不正确。泊松过程不是泊松分布。

通过泊松过程生成到达时间并不意味着像您在代码中那样使用泊松分布。它是通过基于泊松到达率 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