(Bu yaklaşım, yayınladığım bir çözüm de dahil olmak üzere, yayınlanan diğer çözümlerden bağımsız olduğu için, ayrı bir yanıt olarak öneriyorum).
P'nin toplamının küçük olması koşuluyla tam dağılımı saniyeler (veya daha az) olarak hesaplayabilirsiniz.
Dağıtımın yaklaşık olarak Gauss (bazı senaryolar altında) veya Poisson (diğer senaryolar altında) olabileceği yönündeki önerileri gördük. Her iki durumda da, onun ortalama toplamı ve varyansının toplamı olduğunu . Bu nedenle, dağılım, ortalamasının birkaç standart sapması içinde yoğunlaşacaktır, örneğin, 4 ile 6 arasında olan SD'leri veya bunların etrafında. Bu nedenle, sadece toplam olasılığı hesaplamak gerek (bir tam sayı) eşit için ile . çoğup i σ 2 p i ( 1 - p i ) z z X k k = μ - z σ k = μ + z σ p i σ 2 μ k [ μ - z √μpiσ2pi(1−pi)zzXkk=μ−zσk=μ+zσpiküçük, yaklaşık olarak eşittir (ancak biraz daha az) , bu nedenle muhafazakar olmak için için hesaplamayı aralığında yapabiliriz. . Örneğin, toplamı eşittir ve tercih , biz kapağı hesaplama gerekir de kuyrukları kapsayacak şekilde içinde = , bu sadece 28 değerdir.σ2μkpi9z=6k[9-6 √[μ−zμ−−√,μ+zμ−−√]pi9z=6k[0,27][9−69–√,9+69–√][0,27]
Dağılım özyinelemeli olarak hesaplanır . , bu Bernoulli değişkenlerinin ilk toplamının dağılımı olsun . Herhangi biri için gelen ile , ilk toplamı değişkenleri eşit olabilir iki eşsiz ortak yolla: İlk toplamı değişkenlerinin eşit ve olan ya da önce toplamı değişken eşittir ve olan . bu nedenle i j 0 i + 1 i + 1 j i j i + 1 st 0 i j - 1 i + 1 st 1fiij0i+1i+1jiji+1st0ij−1i+1st1
fi+1(j)=fi(j)(1−pi+1)+fi(j−1)pi+1.
Bu hesaplamayı sadece integrali için ila aralığında yapmamız gerekirmax ( 0 , μ - z √j μ+z √max(0,μ−zμ−−√) μ+zμ−−√.
Çoğu zaman küçük (ama hala ayırt olan makul hassasiyetle), bu yaklaşım daha önce yayınlanan çözümde kullanılan hatalar roundoff yüzen noktanın büyük birikimi ile rahatsız olmayan. Bu nedenle, genişletilmiş hassasiyetli hesaplama gerekli değildir. Örneğin, olasılık dizisi için bir çift duyarlıklı hesaplama ( , ile arasındaki toplamların hesaplanmasını gerektirir. 1 - p i 1 2 16 p i = 1 / ( i + 1 ) μ = 10.6676 0 31 3 × 10 - 15 z = 6 3.6 x 10 - 8pi1−pi1216pi=1/(i+1)μ=10.6676031) Mathematica 8 ile 0.1 saniye ve Excel 2002 ile 1-2 saniye sürdü (ikisi de aynı cevapları aldı). Dörtlü hassasiyetle tekrarlamak (Mathematica'da) yaklaşık 2 saniye sürdü, ancak herhangi bir cevabı fazla değiştirmedi . Dağıtımı SD'de üst kuyruğa sonlandırmak, toplam olasılığın yalnızca sini kaybetti .3×10−15z=63.6×10−8
0 ile 0.001 ( ) arasındaki 40.000 çift duyarlıklı rastgele değer dizisi için başka bir hesaplama Mathematica ile 0.08 saniye sürdü.μ=19.9093
Bu algoritma paralelleştirilebilir. Sadece kümesini kırmak yaklaşık olarak eşit boyut, işlemci başına bir ayrık alt-grup halinde. Her alt küme için dağıtımı hesaplayın, ardından tam bir cevap almak için sonuçları toplayın (isterseniz, bu hızlanma muhtemelen gereksiz olsa da FFT kullanarak). Bu bile pratik kullanımı kolaylaştırır büyük olur sen (kuyrukları içine uzaklarda bakmak gerektiğinde, büyük), ve / veya büyüktür. μ z npiμzn
işlemcili bir değişken dizisinin zamanlaması , olarak ölçeklenir . Mathematica'nın hızı saniyede bir milyon civarındadır. Örneğin, ile işlemci, değişkenlerin, toplam olasılık ve çıkıyor üst kuyruğun içine standart sapmalar, milyon: hesaplama süresi için birkaç saniyelik bir rakam. Bunu derlerseniz, performansı iki büyüklük derecesinde hızlandırabilirsiniz.m O ( n ( μ + z √nmm=1n=20000μ=100z=6n(μ+z √O(n(μ+zμ−−√)/m)m=1n=20000μ=100z=6n(μ+zμ−−√)/m=3.2
Bu arada, bu test durumlarında, dağılım grafikleri açıkça bazı pozitif çarpıklıklar göstermiştir: normal değillerdir.
Kayıt için, işte bir Mathematica çözümü:
pb[p_, z_] := Module[
{\[Mu] = Total[p]},
Fold[#1 - #2 Differences[Prepend[#1, 0]] &,
Prepend[ConstantArray[0, Ceiling[\[Mu] + Sqrt[\[Mu]] z]], 1], p]
]
( NB bu site tarafından uygulanan kodlama renk Mathematica kodu için anlamsızdır Özellikle, gri şeyler. Değil yorumlar: tüm çalışma yapıldığı yerle ilgili bu!)
Kullanımına bir örnek
pb[RandomReal[{0, 0.001}, 40000], 8]
Düzenle
Bir R
çözüm, bu test durumunda Mathematica'dan on kat daha yavaş - belki de en iyi şekilde kodlamadım - ama yine de hızlı bir şekilde çalışıyor (yaklaşık bir saniye):
pb <- function(p, z) {
mu <- sum(p)
x <- c(1, rep(0, ceiling(mu + sqrt(mu) * z)))
f <- function(v) {x <<- x - v * diff(c(0, x));}
sapply(p, f); x
}
y <- pb(runif(40000, 0, 0.001), 8)
plot(y)