यह प्रसिद्ध जन्मदिन समस्या का एक सामान्यीकरण है : n=100 व्यक्तियों को, जिन्होंने d=6 संभावनाओं के एक सेट के बीच यादृच्छिक, समान रूप से "जन्मदिन" वितरित किया है , क्या मौका है कि कोई जन्मदिन m=20 व्यक्तियों से अधिक द्वारा साझा नहीं किया जाता है?
एक सटीक गणना से उत्तर (डबल परिशुद्धता के लिए)। मैं सिद्धांत को स्केच करूंगा और सामान्य एन , एम , डी के लिए कोड प्रदान करूंगा । कोड के asymptotic समय है हे ( एन 2 लॉग ( घ ) ) जो यह जन्मदिन की बहुत बड़ी संख्या के लिए उपयुक्त बनाता है d और जब तक उचित प्रदर्शन प्रदान करता है n हजारों में है। उस समय, पोइसन सन्निकटन में चर्चा की गईकि 2 से अधिक लोगों को जन्मदिन के विरोधाभास का विस्तार करने केलिए ज्यादातर मामलों में अच्छा काम करना चाहिए।0.267747907805267n,m,d.O(n2log(d))dn
समाधान की व्याख्या
D -sided मर के स्वतंत्र रोल के परिणामों के लिए प्रायिकता जनरेटिंग फंक्शन (pgf) हैnd
d−nfn(x1,x2,…,xd)=d−n(x1+x2+⋯+xd)n.
के गुणांक इस बहुपद के विस्तार में जिन तरीकों का सामना की संख्या देता है मैं वास्तव में दिखाई दे सकता है ई मैं बार, मैं = 1 , 2 , ... , घ ।xe11xe22⋯xeddieii=1,2,…,d.
से अधिक नहीं करने के लिए हमारे हित सीमित किसी भी चेहरे से दिखावे का मूल्यांकन करने के लिए समान है च n आदर्श सापेक्ष मैं द्वारा उत्पन्न एक्स मीटर + 1 1 , एक्स मीटर + 1 2 , ... , एक्स मीटर + 1 घ । इस मूल्यांकन को करने के लिए, प्राप्त करने के लिए द्विपद प्रमेय का पुन: उपयोग करेंmfnIxm+11,xm+12,…,xm+1d.
चn( x)1, ... , एक्सघ)= ( ( एक्स1+ ⋯ + एक्सआर) + ( x )आर + १+ xआर + २+ ⋯ + एक्स2 आर) )n= ∑k=0n(nk)(x1+⋯+xr)k(xr+1+⋯+x2r)n−k=∑k=0n(nk)fk(x1,…,xr)fn−k(xr+1,…,x2r)
जब सम है। F ( d ) n = f n ( 1 , 1 , … , 1 ) ( d पद) लिखना , हमारे पास हैघ= 2 आरच( d))n= चn( 1 , 1 , … , 1 )घ
च( २) आर )n= ∑के = ०n( एनक) च( आर)कच( आर )n - के।(ए)
जब विषम हो, तो एक अनुरूप अपघटन का उपयोग करेंघ= 2 आर + 1
चn( x)1, ... , एक्सघ)= ( ( एक्स1+ ⋯ + एक्स2 आर) + x2 आर + 1)n= ∑के = ०n( एनक) चक( x)1, ... , एक्स2 आर) चएन - के( x)2 आर + 1) ,
दे रही है
च( 2 आर + 1 )n= ∑के = ०n( एनक) च( 2 आर )कच( 1 )एन - के।(ख)
दोनों मामलों में, हम सब कुछ मोडुलो को भी कम कर सकते हैं , जिसे आसानी से शुरू किया जाता हैमैं
चn( x)जे) ≅{ एक्सn0n ≤ मn > मआधुनिकमैं,
पुनरावृत्ति के लिए शुरुआती मूल्य प्रदान करना,
च( 1 )n= { १0n ≤ मn > म
यह कुशल बनाता है कि चर को आर चर के दो समान आकार वाले समूहों में विभाजित करके और सभी चर मानों को 1 पर सेट करके , हमें केवल एक समूह के लिए एक बार सब कुछ का मूल्यांकन करना होगा और फिर परिणामों को संयोजित करना होगा। इसके लिए n + 1 शब्दों की गणना आवश्यक है, उनमें से प्रत्येक को संयोजन के लिए O ( n ) गणना की आवश्यकता है । हमें f ( r ) n को संग्रहीत करने के लिए 2D सरणी की भी आवश्यकता नहीं है , क्योंकि जब कंप्यूटिंग f ( d ) n , केवल fघआर1 ,एन + १ओ ( एन )च( आर )nच( d))n, औरf ( 1 ) n की आवश्यकता है।च( आर )nच( 1 )n
कुल चरणों की संख्या के बाइनरी विस्तार में अंकों की संख्या से कम है (जो फूट को समान समूहों में सूत्र में विभाजित करता है ( a ) ) प्लस विस्तार में लोगों की संख्या (जो कि सभी बार एक अजीब गणना करता है मूल्य का सामना करना पड़ता है, सूत्र ( बी ) के आवेदन की आवश्यकता होती है । यह अभी भी ओ ( लॉग ( डी ) ) कदम है।घ( ए )( बी )ओ ( लॉग)( d)) )
में R
एक दशक पुरानी कार्य केंद्र पर काम 0.007 सेकंड में किया गया था। इस पोस्ट के अंत में कोड सूचीबद्ध है। यह संभावित ओवरफ्लो से बचने या बहुत अधिक बहने से बचने के लिए, स्वयं संभावनाओं के बजाय, संभावनाओं के लघुगणक का उपयोग करता है। यह समाधान में कारक को हटाने के लिए संभव बनाता है ताकि हम उन गणनाओं की गणना कर सकें जो संभाव्यता को रेखांकित करती हैं।घ- एन
ध्यान दें कि इस प्रक्रिया के परिणामस्वरूप संभाव्यताओं के पूरे क्रम को , एक ही बार में गणना किया जा सकता है, जो आसानी से हमें यह अध्ययन करने में सक्षम बनाता है कि n के साथ संभावना कैसे बदलती है ।च0, च1, … , चnn
अनुप्रयोग
tmultinom.full
एम + १nओ ( एन)2लॉग( n ) लॉग( d)) )nn
#
# The birthday problem: find the number of people where the chance of
# a collision of `m+1` birthdays first exceeds `alpha`.
#
birthday <- function(m=1, d=365, alpha=0.50) {
n <- 8
while((p <- tmultinom.full(n, m, d))[n] > alpha) n <- n * 2
return(p)
}
798birthday(7)
365
कोड
# Compute the chance that in `n` independent rolls of a `d`-sided die,
# no side appears more than `m` times.
#
tmultinom <- function(n, m, d, count=FALSE) tmultinom.full(n, m, d, count)[n+1]
#
# Compute the chances that in 0, 1, 2, ..., `n` independent rolls of a
# `d`-sided die, no side appears more than `m` times.
#
tmultinom.full <- function(n, m, d, count=FALSE) {
if (n < 0) return(numeric(0))
one <- rep(1.0, n+1); names(one) <- 0:n
if (d <= 0 || m >= n) return(one)
if(count) log.p <- 0 else log.p <- -log(d)
f <- function(n, m, d) { # The recursive solution
if (d==1) return(one) # Base case
r <- floor(d/2)
x <- double(f(n, m, r), m) # Combine two equal values
if (2*r < d) x <- combine(x, one, m) # Treat odd `d`
return(x)
}
one <- c(log.p*(0:m), rep(-Inf, n-m)) # Reduction modulo x^(m+1)
double <- function(x, m) combine(x, x, m)
combine <- function(x, y, m) { # The Binomial Theorem
z <- sapply(1:length(x), function(n) { # Need all powers 0..n
z <- x[1:n] + lchoose(n-1, 1:n-1) + y[n:1]
z.max <- max(z)
log(sum(exp(z - z.max), na.rm=TRUE)) + z.max
})
return(z)
}
x <- exp(f(n, m, d)); names(x) <- 0:n
return(x)
}
उत्तर के साथ प्राप्त किया जाता है
print(tmultinom(100,20,6), digits=15)
.267747907805267