Tennis tie-break probability

Tennis tie-break probability

Siamo in una partita di tennis, i due giocatori A e B sono arrivati 6-6 e ora tutto si deciderà al tie-break. Durante la partita, da bravi (ingegneri) matematici, siamo riusciti a stimare due parametri aa e bb che descrivono le probabilità, per il giocatore A, di vincere un punto quando lui è al servizio o quando B è al servizio, rispettivamente. Ma eccoci, il giocatore A si sta apprestando ad iniziare il tie-break! sarà lui infatti a iniziare a servire per primo. Dato questo contesto e questi dati, qual è la probabilità che il giocatore A vinca il tie-break?

Soluzione

Da raccontare a parole è molto lunga, quindi vi suggerisco caldamente il video molto dettagliato. L'idea è comunque intanto di decomporre l'evento vittoria nei possibili casi in cui può manifestarsi, ovvero

P(vincere)=P(vincere 7-0)+P(vincere 7-1)++P(vincere 7-5)++P(vincere 8-6)+P(vincere 9-7)+P(vincere)=P(vincere 7-0)+P(vincere 7-1)++P(vincere 7-5)++P(arrivare 6-6)P(vincere da 6-6) \begin{align*} \mathbb P(\text{vincere}) &= \mathbb P(\text{vincere 7-0}) + \mathbb P(\text{vincere 7-1}) + \ldots + \mathbb P(\text{vincere 7-5}) +\\ & + \mathbb P(\text{vincere 8-6}) + \mathbb P(\text{vincere 9-7}) + \ldots\\ \mathbb P(\text{vincere}) &= \mathbb P(\text{vincere 7-0}) + \mathbb P(\text{vincere 7-1}) + \ldots + \mathbb P(\text{vincere 7-5}) + \\ &+\mathbb P(\text{arrivare 6-6})\mathbb P(\text{vincere da 6-6}) \end{align*}

e poi di studiare ogni termine lavorando con la distribuzione Binomiale. Infatti, una variabile aleatoria XX ha legge Binomiale di parametri nn e pp (e scriviamo XBin(n,p)X\sim\text{Bin}(n,p)) quando XX conta il numero di successi che otteniamo quando replichiamo per nn volte un esperimento che può avere esito di successo con probabilità pari a pp. Quindi l'idea è di trattare nn come il numero di volte in cui un giocatore è al servizio o in risposta, mentre pp come la probabilità dell'evento di "successo", ovvero vincere il punto, ovvero i parametri aa o bb.

Per esempio, per vincere 7-0, il giocatore A deve vincere tutti i punti, dei quali 3 sono quando lui è al servizio mentre 4 di quando B è al servizio. Usando quindi la legge binomiale, che ha densità di probabilità pX(k)=P(X=k)=(nk)pk(1p)nkp_X(k) = \mathbb P(X=k) = \tbinom{n}{k}p^k(1-p)^{n-k}, insieme all'indipendenza degli eventi di vincere un punto, si ricava che

P(vincere 7-0)=P(vincere 3 punti su 3 di quando A eˋ al servizio)P(vincere 4 punti su 4 di quando B eˋ al servizio)=(33)a3(44)b4=a3b4 \begin{align*} \mathbb P(\text{vincere 7-0}) &= \mathbb P(\text{vincere 3 punti su 3 di quando A è al servizio}) \cdot \\ & \mathbb P(\text{vincere 4 punti su 4 di quando B è al servizio}) \\ &= \binom{3}{3}a^3 \binom{4}{4}b^4 = a^3 b^4 \end{align*}

Ovviamente questo era il caso facile. Gli altri sono un po' più complicati (c'è da separare il fatto di arrivare a 6 e poi fare l'ultimo punto vincente, e c'è da capire in quanti modi possono distribuirsi i punti per poter vincere con un certo punteggio) ma seguono la stessa logica.

L'ultimo termine di (1), quello riguardo alla vittoria nei casi ad oltranza, segue invece un calcolo interessante che comporta una ricorsione. Infatti, dal pareggio (tipo 6-6) possiamo vincere o vincendo i due punti successivi (arrivando 8-6) o vincendone uno e perdendone uno, tornando ad un nuovo pareggio (7-7), e vincere partendo da questo nuovo pareggio. In questo modo, usando l'indipendenza dei secondi eventi, abbiamo che

P(vincere dal pareggio)=P(vincere i due punti successivi)+P(tornare al pareggio)P(vincere dal pareggio) \begin{align*} \mathbb P(\text{vincere dal pareggio}) &= \mathbb P(\text{vincere i due punti successivi}) +\\ & \mathbb P(\text{tornare al pareggio})\mathbb P(\text{vincere dal pareggio}) \end{align*}

da cui possiamo quindi ricavare P(vincere dal pareggio)\mathbb P(\text{vincere dal pareggio}). Assemblando tutti i pezzi si arriva alla formulazione che ora segue nel codice e relativi grafici, che descrivono la probabilità di vittoria per il giocatore A, indicata come valori sull'asse zz, in funzione dei parametri aa e bb posti sugli assi xx e yy, e le sue curve di livello.

using Plots
using Distributions 

# 1  2  3  4  5  6  7  8  9  10 11 12
# A  B  B  A  A  B  B  A  A  B  B  A
function ptiebreak(a::Real,b::Real)
    p70 = (pdf(Binomial(3,a),3) * pdf(Binomial(3,b),3))*b 
    # batte B al 7mo turno
    p71 = sum([pdf(Binomial(3,a),i) * pdf(Binomial(4,b),6-i) for i in 2:3])*a 
    # batte A all'8vo turno
    p72 = sum([pdf(Binomial(4,a),i) * pdf(Binomial(4,b),6-i) for i in 2:4])*a 
    # batte A al 9no turno
    p73 = sum([pdf(Binomial(5,a),i) * pdf(Binomial(4,b),6-i) for i in 2:5])*b 
    # batte B al 10mo turno 
    p74 = sum([pdf(Binomial(5,a),i) * pdf(Binomial(5,b),6-i) for i in 1:5])*b 
    # batte B al 11mo turno
    p75 = sum([pdf(Binomial(5,a),i) * pdf(Binomial(6,b),6-i) for i in 0:5])*a
    # batte A al 12mo turno
    p66 = sum([pdf(Binomial(6,a),i) * pdf(Binomial(6,b),6-i) for i in 0:6])
    pda66 = a*b/(1-a-b+2*a*b) 
    
    ptot = p70+p71+p72+p73+p74+p75+p66*pda66
    @assert 0<=ptot<=1
    return ptot
end

aa = range(0.01,0.99, step=0.01)
bb = range(0.01,0.99, step=0.01)
p = surface(aa, bb, ptiebreak,camera=(25,20))
xlabel!("a values")
ylabel!("b values")

contourf(aa, bb, ptiebreak)
xlabel!("a values")
ylabel!("b values")


Notiamo anche come le apparentemente strane regole del tie-break, in cui il primo giocatore effettua solo un servizio e da lì in poi ci si alterna due servizi a testa (quindi la sequenza di battute sarebbe A|BB|AA|BB|AA|...) hanno in realtà ha perfettamente senso. Infatti, il tie-break in questo modo è equo: chiunque cominci al servizio non ha alcun vantaggio a priori. Questo lo si vede anche dalla matematica (naturalmente 😉), in cui leggendo il calcolo sempre nella prospettiva di A, ma nel caso in cui fosse B il primo a servire (possiamo modellare questo scenario invertendo i parametri aa e bb), otterremo comunque le stesse probabilità di vittoria.

Usando i numeri decimali classici (i Float64) sembra che escano valori leggermente diversi; ma in realtà sono solo dovuti ad approssimazioni numeriche: passando ad una rappresentazione più precisa (i BigFloat) tutto dovrebbe tornare.

julia> ptiebreak(0.60,0.70)
0.8881752145777776

julia> ptiebreak(0.70,0.60)
0.8881752145777777

julia> 1-ptiebreak(0.4,0.3) # altro controllo, cambiando prospettiva su B
0.8881752145777779

julia> ptiebreak(BigFloat(0.60),BigFloat(0.70))
0.8881752145777777236370136878239485198844074151971728203443474502251501326155067

julia> ptiebreak(BigFloat(0.70),BigFloat(0.60))
0.8881752145777777236370136878239485198844074151971728203443474502251501326155067

Piccola digressione. A questo punto magari vi chiederete: ma perché allora in informatica non si usano sempre i BigFloat o comunque queste rappresentazioni più precise? La risposta è perché ok, sono più precise, ma sono anche molto molto più dispensiose in termini di memoria e tempo di esecuzione,

julia> @time ptiebreak(BigFloat(0.60),BigFloat(0.70))
  0.012136 seconds (15.61 k allocations: 573.875 KiB)
0.8881752145777777236370136878239485198844074151971728203443474502251501326155067

julia> @time ptiebreak(0.60,0.70)
  0.000018 seconds (6 allocations: 576 bytes)
0.8881752145777776

e anche perché la precisione base è in genere sufficiente. Non sono infatti molti gli scenari in cui i calcoli effettuati da un computer devono avere un così alto livello di precisione.

Last modified: May 27, 2025. Website built with Franklin.jl and the lovely Julia programming language.