(Biraz) Bilgiçlik Günü Paradoksu


20

Arka fon

Doğum günü paradoksu hangi meydan okuyan olasılık teorisinde popüler bir sorunu (çoğu insanın) matematiksel sezgi. Sorun bildirimi:

N kişi göz önüne alındığında , en az ikisinin aynı doğum gününe sahip olma olasılığı nedir (yılı göz ardı ederek).

Sorun genellikle artık günleri tamamen göz ardı ederek basitleştirilir. Bu durumda, için cevap , N = 23 olduğu (23) ≈ 0,5072972 P (ortak bir örnek olarak). Bağlantılı Wikipedia makalesinde bu olasılığa nasıl ulaşılacağı açıklanmaktadır. Alternatif olarak, bu Numberphile videosu gerçekten iyi bir iş çıkarıyor.

Bununla birlikte, bu meydan okuma için doğru yapmak istiyoruz ve artık yılları görmezden gelmiyoruz . Bu, biraz daha karmaşıktır, çünkü şimdi 29 Şubat'ın eklenmesi gerekiyor, ancak bu özel doğum günü diğerlerinden daha az muhtemel.

Ayrıca artık yıl kurallarını da kullanacağız :

  • Bir yıl 400 ile bölünebilirse artık bir yıl olur.
  • Aksi halde, bir yıl 100 ile bölünebilirse artık bir yıl değildir.
  • Aksi takdirde, bir yıl 4 ile bölünebilirse artık bir yıl olur.
  • Aksi halde artık bir yıl değil.

Şaşkın? Bu, 1700, 1800, 1900, 2100, 2200, 2300 yıllarının artık yıl olmadığı, ancak 1600, 2000, 2400 yıllarının (4 ile bölünebilen herhangi bir yıl olduğu) anlamına gelir. Bu takvim her 400 yılda bir tekrarlanır ve doğum günlerinin bu 400 yıl boyunca eşit bir şekilde dağıtılacağını varsayacağız.

N = 23 için düzeltilmiş sonuç şimdi P (23) ≈ 0.5068761'dir .

Meydan okuma

Bir tamsayı verildiğinde , artık yıl kuralları dikkate alınarak en az iki kişinin aynı doğum gününe sahip 1 ≤ N < 100olma olasılığını belirleyin N. Sonuç, en az 6 ondalık basamağa kadar doğru bir kayan nokta veya sabit nokta sayısı olmalıdır. Sondaki sıfırları kısaltmak kabul edilebilir.

STDIN (veya en yakın alternatif), komut satırı bağımsız değişkeni veya işlev bağımsız değişkeni ile girdi alarak ve STDOUT (veya en yakın alternatif), işlev dönüş değeri veya işlev (çıkış) parametresi ile sonuç çıktısı alabileceğiniz bir program veya işlev yazabilirsiniz.

Çözümünüz saniyeler içinde 99 girişin tümü için çıktı üretebilmelidir. Bu esas olarak Monte Carlo yöntemlerini tonlarca örnekle dışlamaktır, bu nedenle aşırı yavaş ezoterik bir dilde temelde hızlı ve kesin bir algoritma kullanıyorsanız, bu kuraldan istifade etmeye hazırım.

Test Durumları

İşte sonuçların tamamı tablosu:

 1 => 0.000000
 2 => 0.002737
 3 => 0.008195
 4 => 0.016337
 5 => 0.027104
 6 => 0.040416
 7 => 0.056171
 8 => 0.074251
 9 => 0.094518
10 => 0.116818
11 => 0.140987
12 => 0.166844
13 => 0.194203
14 => 0.222869
15 => 0.252642
16 => 0.283319
17 => 0.314698
18 => 0.346578
19 => 0.378764
20 => 0.411063
21 => 0.443296
22 => 0.475287
23 => 0.506876
24 => 0.537913
25 => 0.568260
26 => 0.597796
27 => 0.626412
28 => 0.654014
29 => 0.680524
30 => 0.705877
31 => 0.730022
32 => 0.752924
33 => 0.774560
34 => 0.794917
35 => 0.813998
36 => 0.831812
37 => 0.848381
38 => 0.863732
39 => 0.877901
40 => 0.890932
41 => 0.902870
42 => 0.913767
43 => 0.923678
44 => 0.932658
45 => 0.940766
46 => 0.948060
47 => 0.954598
48 => 0.960437
49 => 0.965634
50 => 0.970242
51 => 0.974313
52 => 0.977898
53 => 0.981043
54 => 0.983792
55 => 0.986187
56 => 0.988266
57 => 0.990064
58 => 0.991614
59 => 0.992945
60 => 0.994084
61 => 0.995055
62 => 0.995880
63 => 0.996579
64 => 0.997169
65 => 0.997665
66 => 0.998080
67 => 0.998427
68 => 0.998715
69 => 0.998954
70 => 0.999152
71 => 0.999314
72 => 0.999447
73 => 0.999556
74 => 0.999645
75 => 0.999717
76 => 0.999775
77 => 0.999822
78 => 0.999859
79 => 0.999889
80 => 0.999913
81 => 0.999932
82 => 0.999947
83 => 0.999959
84 => 0.999968
85 => 0.999976
86 => 0.999981
87 => 0.999986
88 => 0.999989
89 => 0.999992
90 => 0.999994
91 => 0.999995
92 => 0.999996
93 => 0.999997
94 => 0.999998
95 => 0.999999
96 => 0.999999
97 => 0.999999
98 => 0.999999
99 => 1.000000

(Tabi ki, p (99) , sadece 1.0 yuvarlama nedeniyle. İhtimali tam ulaşamayacaktır 1,0 kadar (P 367) ).


7
1. Bilgiçlik yapacaksanız, doğum günlerinin yıl boyunca eşit dağılmadığını dikkate almalısınız. 2. Artık yıl kurallarının kesin önemi, insan ömrüne ilişkin varsayımlara bağlıdır. 400 yıllık döngünün tamamında amortisman fikri mi?
Peter Taylor

1
@PeterTaylor Evet, tüm 400 yıllık döngü boyunca eşit dağılım sağlayın. Ben N grubunun aynı anda hayatta olduğunu söylemedim . ;)
Martin Ender

Yanıtlar:


6

Pyth, 31 34 bayt

Jt.2425K366-1c.xX0rK-KQ*JQ^+KJQ

Gösteri , Test Donanımı

Bu, eski sürüme benzer şekilde çalışır, ancak (366 + n * (.2425 - 1)) değerini ayrı ayrı oluşturmak ve çoğaltmak yerine, 366'dan 365 - n + 2'ye uzanan bir liste oluşturarak başlar, daha sonra 366'yı (366 + n * (.2425 - 1)) olacak şekilde değiştirir ve listenin ürününü alır. Ayrıca, 365 ve .2425 yerine 366 ve -.7575 sabitleri kullanılır.


Eski versiyon:

Pyth, 34 bayt

J.2425K365-1c*+hK*QtJ.xrK-hKQ^+KJQ

Aynı doğum gününe sahip bir çift insan olmamasının iki olası yolu vardır: herkesin farklı doğum günleri olması ve hiç kimsenin 29 Şubat'ta doğum günü olması ve birinin 29. doğum gününün doğum günü olması ve diğer herkesin farklı olması normal günlerde doğum günleri.

İlk ortaya çıkma olasılığı (365 * 364 * ... 365 - n + 1) / (365.2425 ^ n).

İkinci gerçekleşme olasılığı (365 * 364 * ... 365 - n + 2) * .2425 * n / (365.2425 ^ n)

Bunlar birlikte (365 * 364 * ... 365 - n + 2) * (365 - n + 1 + .2425 * n) / (365.2425 ^ n) = (365 * 364 * ... 365 - n + 2) * (365 + 1 + (.2425-1) * n) / (365.2425 ^ n).

Bu, hiçbir çiftin olmamasıdır, bu nedenle en az bir çiftin olasılığı bir eksi yukarıdaki sayıdır.

J = .2425
K = 365
.xrK-hKQ = (365 * 364 * ... 365 - n + 2)
+hK*QtJ = (365 + 1 + n * (.2425 - 1))
^+KJQ = (365.2425 ^ n)

5

Python, 179 178 144 143 140 136 135 133

f=.2425
g=365+f
a=lambda n:(n and(365-n)*a(n-1)or 365)/g
b=lambda n:(n<2and f or(367-n)*b(n-1)+a(n-2)*f)/g
p=lambda n:1-a(n-1)-b(n)

p(n)sonucu verir. Değişim .2425için fractions.Fraction(97,400)kesin bir sonuç almak için.


Sen arasına boşluk gerekmez 2ve and.
isaacg

Eğer koymak olamaz 1/için gve bölme yerine onun tarafından?
xnor

@xnor Evet, zamanla bu şeyler kaybolur :) Bir zamanlar optimizasyon neyin daha az olacağı anlamına gelir.
orlp

e=365365'i e ve 367 ile e + 2 olarak tanıtabilir ve değiştirebilirsiniz
Willem

@willem Bu daha kısa değil.
orlp

2

Python 155 153 151 142 140 bayt

d=146097
b=d/400
c=97/d
e=lambda n:n<2and 1-97/d or e(n-1)*(366-n)/b
f=lambda n:n<2and c or f(n-1)*(367-n)/b+e(n-1)*c
a=lambda n:1-e(n)-f(n)

a(n)Sonuç için arayın . Kesin sonuçlar diçin bir kesri sarın .

Burada test edin

Burada kullanılanla aynı tekniği kullanır ancak değiştirilmiş sabitlerle birlikte.


Sen arasına boşluk gerekmez 2ve and.
isaacg

Ben 98 olduğunu düşündüm (bir hesaplama hatası deli olabilir rağmen ...)
Tim

1

80386 makine kodu, 43 bayt

Onaltılık kod:

68 75 6e 33 3b 68 5a eb 07 3b 8b c4 49 d9 e8 d9
e8 d8 00 d9 e8 d9 40 04 de ea d8 c9 d9 00 de eb
e2 f3 d8 ca d9 e8 d8 e1 58 58 c3

Aşağıdaki formülden başladım (tamamlayıcı olasılık için):

\ Ü \ limits_ ^ {k-2} {ı = 0} (1 \ frac {97 + 400 * ı} {d}) * (1-\ frac {303 * (k-1)}, {d})

(işte d = 366 * 400 - 303400 yıldaki gün sayısı)

İşte onu uygulayan c ++ kodu (zaten biraz optimize edilmiştir):

double it_opt(int k)
{
    double d = 366 * 400 - 303; // number of days in 400 years
    double result = 1; // probability of no coincidences
    const float const1 = float(400 / d);
    const float const2 = float(303 / d);
    double v1 = 1 + const2;
    double v2 = 1;

    for (int i = 0; i < k - 1; ++i)
    {
        v1 -= const1;
        result *= v1;
        v2 -= const2;
    }
    result *= v2;
    return 1 - result;
}

Kod, minimum sabit sayısı gerektirecek şekilde düzenlenmiştir - yalnızca iki ( 400 / dve 303 / d). Kullandığım floatdaha az yer (sabit başına 4 bayt) kaplar çünkü onları temsil etmek türü. Buna ek olarak, ben çarpın istemiyordu const2tarafından k - 1(yani dönüştürme gerektirir çünkü k - 1hiç float); kod const2bunun yerine tekrar tekrar çıkarılır .

Montaj dili listesi:

    ; // fastcall convention - parameter k is in ecx
    ; // result must be returned in st
    push dword ptr 0x3b336e75; // const1 = [esp + 4]
    push dword ptr 0x3b07eb5a; // const2 = [esp]
    mov eax, esp;              // use [eax] instead of [esp] - 1 byte less
    dec ecx;                   // calculate k - 1
    fld1;                      // initiaze result = 1
    fld1;                      // initialize v1
    fadd [eax];
    fld1;                      // initialilze v2
myloop:
    fld dword ptr [eax + 4];
    fsubp st(2), st;            // update v1
    fmul st, st(1);             // update result
    fld dword ptr [eax];
    fsubp st(3), st;            // update v2
    loop myloop;                // loop
    fmul st, st(2);             // update result by v2
    fld1;
    fsub st, st(1);             // complement result
    pop eax;                    // restore stack
    pop eax;                    // restore stack
    ret;                        // return
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.