2017-02-08 32 views
5

संभावना है कि n से भरे कमरे में दो लोगों का एक ही जन्मदिन है 1-पी। कहां:बड़ी संख्या के लिए जन्मदिन की संभावना की गणना

p = 365!/365^n(365 - n)! 

जाहिर संख्या इस समीकरण को हल करने के लिए बहुत बड़ा हो जाएगा, इस बारे में जाने के लिए एक रचनात्मक तरीका क्या है?

मैंने सिमुलेशन का उपयोग करके इसे अलग तरीके से हल किया है, लेकिन मुझे लगा कि सूत्र अधिक सुरुचिपूर्ण हो सकता है।

+0

कौन कहता है कि यह गणना करने के लिए बहुत बड़ा है? https://www.johndcook.com/blog/2010/08/16/how-to-compute-log-factorial/ – stark

+0

आप एक bignumber लाइब्रेरी का उपयोग कर सकते हैं, https://gmplib.org/ उदाहरण के लिए – pm100

+0

यदि आप केवल कुछ कंप्यूटेशंस करने की आवश्यकता है, लॉग-गामा फ़ंक्शन का उपयोग यहां दूसरों द्वारा सुझाए गए अनुसार करें। लेकिन अगर आपको कुछ अंतर्दृष्टि प्राप्त करने की आवश्यकता है, तो स्टर्लिंग का फॉर्मूला (https://en.wikipedia.org/wiki/Stirling's_approximation) फैक्ट्रोरियल से जुड़े समस्याओं के लिए एक मानक दृष्टिकोण है। –

उत्तर

3

आप 365 का लाभ ले सकते/(365-एन)! = 365 * 364 * ... * (365- (एन -1))

तो इस शब्द की गणना करने के लिए (इसे ए = 365!/(365-एन) दें!) आप बस उपर्युक्त संख्याएं जैसे कर सकते हैं इस:

unsinged double A=1; // to make sure there is no overflow 
for(int i=0;i<n;i++) A*=365-i; 

एक कदम आगे ले करने के लिए: पी = ए/365^n = (364 * 363 * ... * (365- (n-1)))/365^(n-1) = 364/365 * 363/365 * ... (365- (एन -1))/365।

तो पी इस तरह calcuated जा सकता है:

रैखिक समय

में

unsigned double p=1; 
for(int i=0;i<n;i++) p*= (365-i)/365.0; 

मुझे लगता है कि यह काम करना चाहिए: पी

3

आप पूर्ण फैक्टोरियल की गणना नहीं करना चाहते हैं। इसके बजाय, प्रत्येक शब्द की गणना करें और परिणाम में गुणा करें।

संभावना आप के साथ एक जन्मदिन का हिस्सा नहीं है:

  • 1 व्यक्ति: 364/365
  • 2 लोग: 364/365 * 363/365
  • 3 लोग: 364/365 * 363/365 * 362/365
  • ...

इस देखते हुए, आप p calcuate इस प्रकार है।

int n = 30; 
int i; 
double p = 1; 
for (i = 1; i < n; i++) { 
    p *= (365 - i)/365.0; 
    printf("i=%d, p=%f\n", i, 1-p); 
} 
0

मैं एक समारोह है कि इस तरह दिखता है लिखना होगा:

double p(int n){ 
    double res = 1; 
    while (n>0){ 
     res *= (365 - (n--))/365.0; 
    } 
    return res; 
} 
+0

int काम नहीं करेगा - सभी शर्तें 0 – stark

+0

क्षमा करें मेरा मतलब फ्लोट, या डबल – magicleon

+0

नहीं है: 'res = 0'? – stark

0

एक अन्य समाधान (एक सन्निकटन):

किसी भी दो लोग एक ही जन्मदिन नहीं होने की संभावना 364/365 है । एन लोगों वाले कमरे में, सी (एन, 2) = एन (एन -1)/2 लोगों के जोड़े हैं। तो:

p(n) = 364/365^(n * (n-1)/2) 

और बड़ा n = 100 से, आप सुरक्षित रूप से अगले तालिका का उपयोग कर सकते मूल्यों के लिए:

n p(n) 
1 0.0% 
5 2.7% 
10 11.7% 
20 41.1% 
23 50.7% 
30 70.6% 
40 89.1% 
50 97.0% 
60 99.4% 
70 99.9% 
100 99.99997% 
200 99.9999999999999999999999999998% 
300 (100 − (6×10−80))% 
350 (100 − (3×10−129))% 
365 (100 − (1.45×10−155))% 
366 100% 
367 100% 
0

tgamma(n+1) बहुत n! के करीब है। प्रत्येक *, / के रूप में सटीकता को कम करने के लिए कई बार लूप की आवश्यकता नहीं है प्रत्येक पुनरावृत्ति के साथ थोड़ा सटीकता का गुट खो देता है।

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <float.h> 

long double fact(int n) { 
    return roundl(tgammal(n + 1)); 
} 

double bd_prob(int n) { 
    return fact(365)/(powl(365,n)*fact(365-n)); 
} 

int main(void){ 
    // No problem with 365! 
    printf("fact(365) %Le\n", fact(365)); 
    // No problem with 365 to the 365 power 
    printf("365^365 %Le\n", powl(365, 365)); 

    printf("prob(22) %f\n", bd_prob(22)); 
    exit(EXIT_SUCCESS); 
} 

आउटपुट

fact(365) 2.510413e+778 
365^365 1.725423e+935 
prob(22) 0.524305 
+0

वाह !!! यह शायद मंगल ग्रह के लिए तोड़ देगा। यदि आपके पास हथौड़ा है, तो ... –

+0

@SeverinPappadeux मंगल ठीक दिखता है। 'तथ्य (1754)' -> 1.979262 ई + 4 9 30। [मार्टिन साल] (https://en.wikipedia.org/wiki/Timekeeping_on_Mars#Martian_year) <~ 68 9 पृथ्वी के दिन या ~ 669 मंगल के दिन है। इसके ~ 1680 पृथ्वी दिनों के साथ [सेरेस "वर्ष"] (http://space-facts.com/ceres/) के लिए भी अच्छा है। – chux

4

होली मैकरोनी! क्या एक शो!

वैसे भी, बड़े मध्यवर्ती के साथ ऐसी बातें गणना करने के लिए सही तरीके से प्रवेश करने के लिए() उन्हें

p = exp(log(p)) 

log(p) = log(365!) - n*log(365) - log((365 - n)!) 

भाज्य के लिए, गामा फ़ंक्शन, जी का उपयोग करें (n + 1) = n !, और बहुत आसान है सी पुस्तकालय में समारोह जो लॉग (जी (x)) की गणना करता है: lgamma (एक्स)

कोई और अधिक छोरों, कोई लंबी युगल, कोई bignum पुस्तकालयों, कोई अतिप्रवाह ...

कोड

#include <math.h> 
#include <stdio.h> 

double b(int n) { 
    double l = lgamma(365.0 + 1.0) - 
       (double)n * log(365.0) - 
       lgamma(365.0 - (double)n + 1.0); 

    return exp(l); 
} 

int main() { 
    double p = b(20); 
    printf("%e %e\n", p, 1.0 - p); 

    return 0; 
} 
+0

यह सबसे अच्छा तरीका है। मामूली: '(डबल)' कास्ट की आवश्यकता नहीं है। – chux

संबंधित मुद्दे