Testo. Si esegue l'algoritmo della mediana per campionamento su n=106+1 numeri distinti: campione di m=⌈n3/4⌉ elementi con reinserimento, d e u ai ranghi m/2∓n del campione, C={x:d≤x≤u}, si ricomincia se la mediana non è in C o se ∣C∣>4m.
Calcolare m, n, il numero atteso di elementi in C e il costo di un giro in confronti.
Dimostrare che la probabilità che d sia sopra la mediana è al più 41n−1/4 e calcolare il limite per l'intero fallimento.
Rifare il limite con Hoeffding al posto di Chebyshev.
Confrontare con una simulazione.
Soluzione
1. Parametri.n3/4=104,5=31622,8, quindi m=31623; n=1000,0005≈1000 (la mediana ha rango k=500001). I due estremi distano 2n=2000 ranghi nel campione di m elementi, cioè una frazione m2000 dell'insieme: ∣C∣≈n⋅m2n=2n3/4≈63246≈2m, ben sotto il limite 4m=126492. Un giro costa:
ordinare il campione: O(mlogm), circa 31623⋅15≈4,7×105 operazioni;
confrontare ogni elemento con d e con u: 2n=2000002 confronti;
ordinare C: O(∣C∣log∣C∣), circa 63246⋅16≈106.
In totale circa 2×106+1,5×106=3,5×106 confronti, contro nlog2n≈2×107 dell'ordinamento diretto. Asintoticamente domina 2n, perché i due ordinamenti costano O(n3/4logn)=o(n); per n=106 però pesano ancora quasi quanto il passaggio sull'input.
2. Limite di Chebyshev. Sia Y il numero di elementi del campione che sono ≤ mediana: Y∼Bin(m,q) con q=nk≥21. Se d> mediana, meno di m/2−n campioni sono ≤ mediana, cioè Y<m/2−n≤E[Y]−n. Con Var(Y)=mq(1−q)≤4m e Chebyshev:
P(Y≤E[Y]−n)≤nm/4=4nn3/4=41n−1/4=41⋅0,0316=0.0079.
Gli altri tre eventi cattivi (la mediana sopra u, u oltre il rango k+2m, d sotto k−2m) hanno la stessa limitazione, quindi
P(giro fallito)≤4⋅0,0079=n−1/4=0.0316.
In media si fanno meno di 1−0,03161=1,033 giri.
3. Limite di Hoeffding.Y è somma di m indicatori indipendenti: P(Y≤E[Y]−n)≤e−2(n)2/m=e−2n/m=e−2n1/4=e−63,2=3,4×10−28. Per i quattro eventi ≤1,4×10−27: la probabilità di fallimento passa da 3×10−2 a 10−27: il limite di Chebyshev è molto prudente.
4. Simulazione. Su 300 esecuzioni con n=106+1: 0 giri falliti, ∣C∣ medio 63161 (da 59184 a 66657, previsto ≈2m=63246), quindi il costo di un giro resta quello stimato al punto 1.
import math
import numpy as np
n = 10**6 + 1
m = math.ceil(n**0.75); r = math.isqrt(n); k = (n + 1) // 2print(m, r, n**-0.25, 4 * math.exp(-2 * n / m)) # 31623 1000 0.0316 1.4e-27
rng = np.random.default_rng(1)
a = np.arange(n) # i numeri sono 0..n-1, la mediana e' n // 2
falliti, dim = 0, []
for _ inrange(300):
R = np.sort(rng.integers(0, n, size=m)) # campione con reinserimento (valori = ranghi)
d, u = R[m // 2 - r - 1], R[m // 2 + r]
sotto, sopra = (a < d).sum(), (a > u).sum()
C = ((a >= d) & (a <= u)).sum(); dim.append(C)
falliti += not (sotto < k and sopra < k and C <= 4 * m)
print(falliti, np.mean(dim)) # 0 ~63200
Costo. Confronti con d e u: 2n; ordinamenti di R e C: O(mlogm), circa 1,5×106. Totale ≈3,5×106 contro nlog2n≈2×107.
Chebyshev.Y∼Bin(m,q), q≥21, Var(Y)≤4m. d sopra la mediana richiede Y≤E[Y]−n: probabilità ≤nm/4=41n−1/4=0,0079. Quattro eventi: fallimento ≤n−1/4=0,0316, quindi in media 1,033 giri.