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 a 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.

a bb aa 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 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}, 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}) + \\ &+ \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 segue invece un calcolo interessante, tramite una definizione ricorsiva. Infatti, pensando all'evento (vincere da 6-6) come in generale un evento del tipo (vincere dal pareggio), 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*}

dove quindi si può ricavare P(vincere dal pareggio)\mathbb P(\text{vincere dal pareggio}) da questa sua definizione ricorsiva. Assemblando tutti i pezzi si arriva alle parti che ora seguono (codice e grafici). Ad esempio si nota come all'aumentare di aa e bb aumentano anche le probabilità di vittoria, come è naturale che sia.

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::Float64,b::Float64)
    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")
Il grafico che segue mostra 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.

Notiamo anche come il tie-break, in cui il primo a servire fa solo un servizio e poi dal primo punto in poi ci si alterna due servizi a testa (quindi la sequenza di battute sarebbe ABBAABBAA...), ha questa apparentemente strana regola che in realtà funziona benissimo. Infatti il tie-break in questo modo è equo: chiunque cominci al servizio non ha un vantaggio a priori. Questo lo si vede anche dai calcoli (naturalmente 😉), in cui leggendo il calcolo sempre nella prospettiva di A, ma nel caso in cui fosse B il primo a servire (e quindi dovremmo invertire i parametri aa, e bb), otterremo comunque le stesse probabilità di vittoria.

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

julia> ptiebreak(0.60,0.70)
0.8881752145777776

julia> ptiebreak(0.70,0.60)
0.8881752145777777

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

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

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 è sia perché ok sono più precise ma sono anche 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 sia 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: January 05, 2025. Website built with Franklin.jl and the lovely Julia programming language.