2012-03-23 36 views
2

我想創建一個Java中的函數,根據平均到達率(lambda)和平均服務率(mu)生成泊松到達。在Java中生成泊松到達

在我的例子中,我有: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

有人可以幫我嗎?

謝謝

安娜

+2

什麼是阻止你這樣做的具體問題? – 2012-03-23 01:20:23

+0

[模擬泊松等待時間 - Java]的可能的副本(http://stackoverflow.com/questions/6527345/simulating-poisson-waiting-times-java) – duffymo 2012-03-23 01:21:26

+1

歡迎來到SO。請閱讀[常見問題]和[問]以瞭解如何在此發佈問題的詳細信息。如果沒有證據表明您已經嘗試解決問題,則會被視爲超出範圍。 SO用戶提供特定問題的答案,但通常不會爲您完成工作。此外,您希望在發佈之前在網上和SO上搜索答案。 – 2012-03-23 01:22:36

回答

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)被四捨五入爲零......哎呀!)

4

您可以使用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; 
} 

要理解它是如何工作的注意,之後ķ迭代循環條件變得

p * p * ...... * p ķ>大號

這相當於

-ln(P )/平均-ln(P )/平均... -ln(P ķ)/平均> 1

請注意,如果p是均勻分佈的,則-ln(p)/ mean具有給定均值的指數分佈。具有泊松分佈的隨機變量等於事件之間的間隔長度爲具有指數分佈的獨立隨機變量時在給定事件發生在固定間隔內的次數。由於我們使用泊松分佈的平均值作爲事件之間間隔的指數分佈的均值,因此我們統計事件的固定內部是單位長度。因此,循環條件總結了事件間隔的長度並檢查我們是否超出了單位間隔。如果我們在計數第k個事件時已經超出了單位間隔,那麼k-1個事件在間隔內發生,因此我們返回k-1。

+0

這是Knuth的方法。如果您可以接受生成時間來等待下一個事件,那麼您可以使用此:[http://stackoverflow.com/a/15307412/1650437](http://stackoverflow.com/a/15307412/1650437) – jdbertron 2013-03-09 05:10:59

1

我發現這個解決方案,使用逆變換採樣:

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次

sleep(floor(-1.0 * log(1.0 - rand()* 1.0/RAND_MAX)/ rate));

+0

由遠遠是最好的方法 – 2014-03-26 18:31:05