In acest notebook calculam probabilitatile evenimentelor $E_n$, ca intr-un grup de n persoane, $2\leq n\leq 365$, sa existe cel putin doua cu aceeasi zi de nastere si vizualizam comparativ aceste probabilitati.
Apoi generam aleator zilele de nastere si verificam ca probabilitatile experimentale sunt foarte apropiate de cele teoretice.
Formula teoretica de calcul a probabilitatii a cel putin unei coincidente a zilelor de nastere intr-un grup de $n$ persoane, dedusa in Cursul 7, este:
$P(E_n)=1-\displaystyle\prod_{k=1}^{n-1}\left(1-\displaystyle\frac{k}{365}\right)$
Definim functia recursiva prob_theor
ce calculeaza probabilitatea evenimentului complementar
$P(\complement E_n)=\displaystyle\prod_{k=1}^{n-1}\left(1-\displaystyle\frac{k}{365}\right)$
In [1]:
from __future__ import division
In [2]:
def prob_theor(n):
if n==2:
return (1-1/365)
else:
return prob_theor(n-1)*(1-(n-1)/365)
In [3]:
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('ggplot') # setam stilul de afisare a plot-urilor.
# Incepand cu matplotlib 1.4 s-au introdus mai multe stiluri
# http://matplotlib.org/users/style_sheets.html
In [4]:
plt.rcParams['figure.figsize'] = (8.0, 4.0)
Calculam acum probabilitatile de coincidenta a cel putin 2 zile de nastere intr-un grup de $n$ persoane cu $2\leq n\leq 60$ si le reprezentam grafic:
In [5]:
nrPartic=60
probsEn=[1- prob_theor(n) for n in range(2,nrPartic+1)]
n=[ k for k in range(2, nrPartic+1)]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.stem(n, probsEn, 'b', bottom=0)
ax.set_xlabel('n')
ax.set_ylabel(r'$P(E_n)$')
ax.set_title('Probabilitatile $P(E_n)$, $n=2,\ldots, 60$')
Out[5]:
Afisam probabilitatile calculate:
In [6]:
import numpy as np
print np.array(probsEn).round(3)
Pentru a verifica experimental problema zilei de nastere, prezentam mai intai cateva elemente de programare Python ce le vom folosi.
Vom genera un dictionar ce are drept chei zilele de nastere de la 1 la 365 inclusiv si fiecarei chei ii atribuim numarul de persoane din cele $n$ ce au acea zi de nastere.
Pentru a crea dictionarul in mod compact si nu explicit, procedam astfel: general lista nrbdays=[0]*365
de lungime 365, ce are setate toate elementele pe $0$ (la inceputul experimentuluinu stim inca zilele de nasere ale participantilor).
In general unei liste L=[2, 3, 'u', 'z']
i se asociaza o lista de cupluri $(i, L[i])$ apeland functia enumerate(L)
:
In [7]:
L=[2, 3, 'u', 'z']
print list(enumerate(L))
Pentru a incepe numararea de la 1, nu de la 0, setam startul astfel:
In [8]:
print list(enumerate(L, start=1))
Astfel din lista nrbdays
generam dictionarul de interes astfel: birthdays=dict(enumerate(nrbdays, start=1))
.
Cu alte cuvinte, dictionarul va avea drept chei "numerele de ordine" al perechii
In [9]:
nrbdays=[0]*365
birthdays=dict(enumerate(nrbdays, start=1))
print birthdays
Pentru simulare importam functia randint(m,n)
care genereaza uniform (cu aceeasi probabilitate) numere din multimea de intregi $\{m,m+1, \ldots, n\}$, $m<n$.
In [10]:
from random import randint
def bdayExper(nrP=23): #nrP= numarul de participanti la chef
#generam aleator cate o zi de nastere si marim cu 1 contorul ce da nr de participandti nascuti in acea zi
# calculam si returnam nr de coincidente
coincidence=0 # initial nu exista nicio coincidenta
nrbdays=[0]*365 #numarul initial de participanti nascuti intr-o zi a anului este 0
birthdays=dict(enumerate(nrbdays, start=1)) # creaza dictionarul {1:0, 2:0, ...., 365:0}
for n in range(nrP):
birthdays[randint(1,365)]+=1 #actualizam datele din dictionar
for k in birthdays.keys(): # parcurgem dictionarul si numaram cate coincidente s-au inregistrat
# intr-o singura simulare
if birthdays[k]>1:
coincidence+=1
return coincidence
Acum repetam experimentul aleator de $N$ ori cu acelasi nr de participanti si calculam nr de coincidente in fiecare incercare:
In [11]:
N=1000
nrP=30
Lcoinc=[bdayExper(nrP=30) for k in range(N)]# lista numarului de coincidente in fiecare incercare din cele N
#E mai simplu sa numaram cate incercari exista fara nicio coincidenta:
NrCoinc0=Lcoinc.count(0)# numarul de incercari cu nicio coincidenta
print 'Probabilitate experimentala a cel putin unei coincidente intr-un grup de ', nrP, 'persoane este:',\
1.0*(N-NrCoinc0)/N, '\n', 'Probabilitatea teoretica:', 1-prob_theor(nrP)
In [12]:
print 'Lista numarului de coincidente in fiecare incercare din cele N', Lcoinc
In [13]:
from IPython.core.display import HTML
def css_styling():
styles = open("./custom.css", "r").read()
return HTML(styles)
css_styling()
Out[13]: