在Java中生成Poisson到达

时间:2012-03-23 01:16:43

标签: java poisson

我想在Java中创建一个函数,根据平均到达率(lambda)和平均服务率(mu)生成Poisson到达。

在我的例子中,我有:2,2个请求/天,换句话说2,2个到达/天,平均服务时间为108个小时。考虑到我的程序在t = 0分钟开始,我想创建一个返回到达[]的函数,它将包含t1,t2和一个可能的t3。 T1,t2和t3是这些到达发生的白天的瞬间(以分钟为单位)。我有以下限制:

t1 < t2 < t3 < 1440 minutes (24 hours*60 minutes/hour)

t2-t1 > 108 minutes

t3-t2 > 108 minutes

t3+ 108 minutes < 1440 minutes

有人可以帮帮我吗?

谢谢,

安娜

4 个答案:

答案 0 :(得分:5)

您可以使用this algorithm proposed by D. Knuth

private static int getPoissonRandom(double mean) {
    Random r = new Random();
    double L = Math.exp(-mean);
    int k = 0;
    double p = 1.0;
    do {
        p = p * r.nextDouble();
        k++;
    } while (p > L);
    return k - 1;
}

要理解这是如何工作的,请注意在 k 迭代之后,循环条件变为

p 1 * p 2 * ... * p k &gt; →

相当于

-ln(p 1 )/ mean -ln(p 2 )/ mean ... -ln(p k )/意思是&gt; 1

请注意,如果 p 均匀分布,则-ln(p)/ mean具有指定均值的指数分布。当事件之间的间隔长度是具有指数分布的独立随机变量时,具有泊松分布的随机变量等于给定事件在固定间隔内发生的次数。由于我们使用泊松分布的均值作为事件之间间隔的指数分布的均值,因此我们计算出现次数的固定内部是单位长度。因此,循环条件总结了事件之间间隔的长度,并检查我们是否超出了单位间隔。如果我们在计算第k个事件时已超出单位间隔,则在该区间内发生k-1个事件,因此我们返回k-1。

答案 1 :(得分:2)

我使用逆变换采样找到了这个解决方案:

http://preshing.com/20111007/how-to-generate-random-timings-for-a-poisson-process

它不使用拒绝抽样方法,效率高且准确。

它使用事件之间的时间分布是指数分布的事实,参数lambda是到达率。 指数分布是lambda exp(-lambda x)。 为了从该分布中采样值并避免拒绝采样,使用其累积分布函数(CDF)更容易:1 - exp(-lambda x)。 CDF是一个从0.0开始的函数,并且使用larget参数增长到1.0。 直觉上,随着时间的推移,你获得事件的可能性会增加。

为了对CDF进行采样,并再次避免拒绝采样,更容易在[0,1]之间选择一个均匀的随机数U并在CDF的反函数中插入该值,这给出:nextEvent = - Ln (U)/λ。 因为Ln(0)未定义,并且大多数随机数生成器包含0.0并且排除1.0,所以使用它更安全: nextEvent = -Ln(1.0-U)/ lambda。 如果您的代码使用基于毫秒的时间/睡眠功能,您可以使用:

倍率= 20.0 / 1000.0; //平均每秒20次

睡觉(楼层(-1.0 * log(1.0 - rand()* 1.0 / RAND_MAX)/ rate));

答案 2 :(得分:0)

这是一些生成带有给定均值的泊松数的简化代码:

private static int poisson(double mean) {
    int r = 0;
    double a = random.nextDouble();
    double p = Math.exp(-mean);

    while (a > p) {
        r++;
        a = a - p;
        p = p * mean / r;
    }
    return r;
}

您应该可以使用此类似的东西来生成每个时间段的到货号码:输入应该是您在此期间预期到达的平均次数。

请注意,如果您的平均值非常大(例如500+),您将需要估算具有正态分布的到达数量。这样更有效,而且它避免了上面代码中固有的数值溢出问题(在某些时候Math.exp(-mean)被舍入为零...... ooops!)

答案 3 :(得分:0)

您可以将其添加到build.gradle

implementation 'org.kie.modules:org-apache-commons-math:6.5.0.Final'

并使用PoissonDistribution more detail