Compleanni coincidenti

Olimpiadi Italiane di Statistica 2011 E.M. – 2

Qual è la probabilità che in una classe di 25 alunni, almeno due compiano gli anni lo stesso giorno?


Versione 1

Metodo probabilistico: genera 25 giorni di nascita casuali e controlla se ci sono coincidenze, ripete 1000 volte.

import random                             # randint()
  
INCONTRI = 1000                           # Numero di incontri
PERSONE  = 25                             # Numero di persone presenti

coincidenze = 0
for incontro in range(INCONTRI):
    anno = [False]*366                    # Tutti i giorni NON presenti
    for compleanno in range(PERSONE):
        giorno = random.randint(1, 365)   # Un giorno a caso (da 1 a 365)
        if(anno[giorno]):
            coincidenze += 1 
            break
        else:
            anno[giorno] = True           # Il giorno adesso è presente
  
frequenza = coincidenze/INCONTRI
print(frequenza)

Versione 2

La struttura dati set permette di gestire facilmente l’assenza / presenza di un certo giorno.
Se il numero di giorni presenti nell’insieme anno è inferiore al numero di PERSONE allora c’è stata almeno una coincidenza.

import random
 
INCONTRI = 1000
PERSONE  = 25
 
coincidenze = 0
for incontro in range(INCONTRI):
    anno = set()
    for compleanno in range(PERSONE):
        giorno = random.randint(1, 365)
        anno.add(giorno)
    if(len(anno) < PERSONE):
        coincidenze += 1
 
frequenza = coincidenze/INCONTRI
print(frequenza)

Versione 3

Vedi la discussione

Con la formula: la probabilità con 25 persone è superiore al 50%

import matplotlib.pyplot as plt

PERSONE = 25
ANNO    = 365
pNo     = (PERSONE+1)*[0]
pSì     = (PERSONE+1)*[0]
pNo[0]  = 1
pSì[0]  = 0
pNo[1]  = 1
pSì[1]  = 0

for n in range(2, PERSONE+1):
    pNo[n] = pNo[n-1]*(ANNO-(n-1))/ANNO
    pSì[n] = 1-pNo[n]

for n in range(0, PERSONE+1):
    print("%2i %f %f" %(n, pNo[n], pSì[n]))

N = range(0, PERSONE+1)
    
plt.grid()
plt.plot(N, pNo)
plt.plot(N, pSì)
plt.legend(["No", "Sì"])
plt.title("Compleanni coincidenti")
plt.xlabel("Numero persone")
plt.ylabel("Probabilità")

plt.show()

Aumentando il numero di persone a 60 si può notare che la probabilità è molto vicina al 100%