2016-04-03 11 views
0

Nur versuchen, Geburtstagsparadox zu verstehen. Mit einem folgenden Code habe ich herausgefunden, dass ich im Durchschnitt 12 Proben um eine Geburtstagskollision zu bekommen brauchen.
Kann nicht verstehen, warum es viel niedriger ist als normal 23 Menschen, um eine Chance von 1/2 Geburtstagskollision zu bekommen. Das Ergebnis ändert sich nicht, selbst wenn ich StrongRandom von PyCrypto verwende.Wie viele Proben für eine Kollision benötigt werden (Geburtstagsparadox)

from random import randint 
from Crypto.Random.random import StrongRandom 
EXPERIMENTS_NUM = 10000 
SET_SIZE = 365 
SUBSET = 23 

where_collision_found = list() 
rnd = StrongRandom() 
for experiment in range(EXPERIMENTS_NUM): 
    for i in range(1,SET_SIZE + 2): 
    collision_found = False 
    #Generate a subset 
    # subset = [rnd.randint(1, SET_SIZE) for x in range(i)] 
    subset = [randint(1, SET_SIZE) for x in range(i)] 
    # Check for collision 
    flags = [False for x in range(SET_SIZE + 1)] 
    for k in range(i): 
     if flags[subset[k]]: #Collision found 
     collision_found = True 
     else: 
     flags[subset[k]] = True 

    if collision_found: 
     # print 'Collision found in set:', subset 
     break 
    where_collision_found.append(i) 
print 'average collision:', sum(where_collision_found)/float(len(where_collision_found)), 'in', EXPERIMENTS_NUM, 'experiments' 

Ergebnis:
average collision: 12.1277 in 10000 experiments

+0

Was ist die Bedeutung der Summierung 'where_collision_found'? –

+0

nur um den Durchschnitt zu erhalten: 'sum/count' – Sergey

+1

' where_collision_found' ist der Tag des Jahres oder '366' wenn keine Kollision. Der Durchschnitt ist nicht die Wahrscheinlichkeit einer Kollision. –

Antwort

2

Ich bin nicht wirklich klar, was Ihr Code tut. Hier ist, was ich habe gerade jetzt:

from random import randrange 
N = 365 
ns = [] 
for _ in range(10000): 
    n = 0 
    seen = set() 
    while True: 
     b = randrange(N) 
     n += 1 
     if b in seen: 
      break 
     seen.add(b) 
    ns.append(n) 
print(sum(ns)/float(len(ns))) 

Und Ausgabe von einem Probelauf:

24.6577 

Das ist gut. Die "23", die Sie erwarten, ist der Median der Verteilung; der Mittelwert (Durchschnitt) wird voraussichtlich 24.61659 sein ... Siehe hier: https://en.wikipedia.org/wiki/Birthday_problem#Average_number_of_people

+0

Vielen Dank für die klare Darstellung, aber ich verstehe immer noch nicht, warum mein Code nicht etwas über ~ 24 ... – Sergey

+0

Ich ehrlich gesagt don Ich weiß nicht, was dein Code berechnet. Sie zwingen Untermengen (wirklich Listen - Auswahlen mit Ersatz) zu vielen spezifischen, zunehmenden Größen, was nichts mit dem zugrunde liegenden Problem zu tun hat. Es ist nicht der Code, der repariert werden muss - es ist Ihre Modellierung des Problems. Der Code, den ich gab, zeigt eine einfache Modellierung des Problems - und nicht zu überraschend, mit einem korrekten * Modell * sind die Ergebnisse wie erwartet. –

+0

Nun, in Ihrem Beispiel ist jede Teilmenge in der Iteration abhängig von der vorherigen (weil Sie einfach einen neuen Wert anhängen). Ich nehme an, es ist nicht die beste Art der Zufallsstichprobe aus irgendeinem Set. In meinem Beispiel erzeuge ich neue Teilmengen in jeder Iteration und dies beeinflusst irgendwie das Ergebnis. Ich denke, ich muss wirklich das Thema studieren, aber weiß nicht wo (Wikipedia, leider hat nicht geholfen) – Sergey