Salta al contenuto
Note per Studenti Esercizio - Probabilità esatte di Karger sul ciclo e sul grafo completo

Esercizio - Probabilità esatte di Karger sul ciclo e sul grafo completo

Testo. Si considera l'algoritmo di contrazione di Karger.

  1. Sul ciclo C5C_5 (vertici 1,…,51,\dots,5, archi 12,23,34,45,5112,23,34,45,51) calcolare la probabilità che esca un taglio minimo specifico, per esempio la coppia {12,34}\{12,34\}. Confrontarla col limite 1/(n2)1/\binom n2.
  2. Sul grafo completo K4K_4 calcolare la probabilità che esca il taglio {d}\{d\} (vertice dd da solo) e quella che esca un taglio minimo qualunque.
  3. Quante esecuzioni indipendenti servono su K4K_4 per fallire con probabilità ≤1%\le1\%? Quante darebbe il limite generale?
  4. (Verifica con un programma) Probabilità esatte su K5K_5.

Teoria: Taglio minimo randomizzato - algoritmo di KargerTaglio minimo globale di un multigrafo con n vertici. Algoritmo di Karger: finché restano più di 2 vertici, scegliere un arco uniformemente tra i rimasti e contrarlo (fondere gli estremi, tenere i paralleli, togliere i cappi); gli archi tra i due supervertici finali sono un taglio. Un taglio minimo C di k archi sopravvive se nessun suo arco viene contratto; con n_i vertici il grado minimo è ≥ k, quindi |E_i| ≥ n_i k/2 e Pr[contrarre un arco di C] ≤ 2/n_i; il prodotto telescopico dà Pr[output = C] ≥ 2/(n(n-1)) = 1/C(n,2). Con t = C(n,2) ln(1/δ) ripetizioni indipendenti il fallimento è ≤ δ. Corollario: un grafo ha al più C(n,2) tagli minimi (stretto per il ciclo). Karger-Stein: contrarre fino a n/√2+1 vertici (sopravvive con prob ≥ 1/2) e ricorrere due volte, T(n) = O(n² log n), successo Ω(1/log n).Taglio minimo randomizzato - algoritmo di Karger → (sezione sulla stretta del limite).

Soluzione

Punto 1. Nel ciclo ogni vertice ha grado 22 e, dopo ogni contrazione, il grafo resta un ciclo (più corto) che ha nin_i vertici e nin_i archi. Il taglio minimo vale k=2k=2 e in ogni passo ∣Ei∣=ni=nik2|E_i|=n_i=\frac{n_ik}{2}: la disuguaglianza ∣Ei∣≥nik/2|E_i|\ge n_ik/2 della dimostrazione è un'uguaglianza. Quindi la probabilità di non scegliere un arco di C={12,34}C=\{12,34\} al passo ii vale esattamente 1−2ni1-\frac2{n_i} (e il taglio specifico è un taglio minimo del ciclo contratto). I passi sono ni=5,4,3n_i=5,4,3: Pr⁡[output=C]=(1−25)(1−24)(1−23)=35⋅12⋅13=110=1(52).\Pr[\text{output}=C]=\Big(1-\frac25\Big)\Big(1-\frac24\Big)\Big(1-\frac23\Big)=\frac35\cdot\frac12\cdot\frac13=\frac1{10}=\frac1{\binom52}. Il limite è raggiunto: nel ciclo è la probabilità esatta di ciascuno dei (52)=10\binom52=10 tagli minimi (le coppie di archi), e la somma è 10⋅110=110\cdot\frac1{10}=1: l'output è sempre un taglio minimo.

Punto 2. In K4K_4 ogni vertice ha grado 33, k=3k=3, n=4n=4, il limite è 16\frac1{6}. Per ottenere {d}\{d\} non si deve mai contrarre un arco incidente a dd.

  • Primo passo: 66 archi, 33 incidenti a dd: si evita con 36=12\frac36=\frac12. Si contrae, per esempio, abab: nasce w={a,b}w=\{a,b\}.
  • Secondo passo: il multigrafo ha vertici w,c,dw,c,d e archi wcwc (doppio: acac, bcbc), wdwd (doppio: adad, bdbd), cdcd (singolo): 55 archi. Si evita dd solo contraendo wcwc: probabilità 25\frac25.
  • Alla fine restano {w,c}\{w,c\} e dd, con 33 archi: il taglio {d}\{d\}.

Pr⁡[output={d}]=12⋅25=15=0,2 ≥ 16.\Pr[\text{output}=\{d\}]=\frac12\cdot\frac25=\frac15=0{,}2\ \ge\ \frac16 . Per simmetria vale lo stesso per ciascuno dei 44 tagli a vertice singolo (i soli tagli minimi, di dimensione 33); i tagli 2+22+2 hanno 44 archi. Probabilità di un taglio minimo qualunque: 4⋅15=454\cdot\frac15=\frac45. Si verifica anche direttamente: all'ultimo passo, con vertici w,c,dw,c,d e archi 2,2,12,2,1, il taglio finale ha dimensione 33 se si contrae wcwc o wdwd (25+25=45\frac25+\frac25=\frac45) e dimensione 44 se si contrae cdcd (15\frac15).

Punto 3. Un'esecuzione fallisce (non trova un taglio minimo) con probabilità 15\frac15. Serve (1/5)t≤0,01(1/5)^t\le0{,}01, t≥ln⁡100ln⁡5=4,6051,609=2,86t\ge\frac{\ln100}{\ln5}=\frac{4{,}605}{1{,}609}=2{,}86, quindi t=3t=3 (0,0080{,}008). Il limite generale darebbe t=⌈(42)ln⁡100⌉=⌈27,6⌉=28t=\lceil\binom42\ln100\rceil=\lceil27{,}6\rceil=28.

Punto 4. In K5K_5 ogni vertice ha grado 44, quindi k=4k=4 e i tagli minimi sono i cinque a vertice singolo (un taglio 2+32+3 ha 66 archi). A mano, per il taglio {e}\{e\}:

  • primo passo: 1010 archi, 44 incidenti a ee, si evita ee con 610=35\frac6{10}=\frac35; per simmetria si contrae abab e nasce ww;
  • secondo passo: archi wc,wd,wewc,wd,we doppi e cd,ce,decd,ce,de singoli, 99 in tutto; quelli che non toccano ee sono wcwc (22), wdwd (22), cdcd (11);
  • terzo passo, se si è contratto wcwc (probabilità 29\frac29): nasce {a,b,c}\{a,b,c\} con 33 archi verso dd, 33 verso ee e l'arco dede, 77 archi; si evita ee solo con i 33 verso dd: 37\frac37. Lo stesso se si è contratto wdwd (29\frac29);
  • terzo passo, se si è contratto cdcd (19\frac19): nasce {c,d}\{c,d\} con 44 archi verso ww, mentre ww ha 22 archi verso ee e {c,d}\{c,d\} altri 22: su 88 archi, 44 evitano ee, cioè 12\frac12.

Pr⁡[output={e}]=35(49⋅37+19⋅12)=35⋅31126=31210=0,1476 ≥ 110.\Pr[\text{output}=\{e\}]=\frac35\Big(\frac49\cdot\frac37+\frac19\cdot\frac12\Big)=\frac35\cdot\frac{31}{126}=\frac{31}{210}=0{,}1476\ \ge\ \frac1{10}. Un taglio minimo qualunque esce con 5⋅31210=3142=0,7385\cdot\frac{31}{210}=\frac{31}{42}=0{,}738. Il programma sotto enumera tutte le sequenze di contrazioni con le frazioni e conferma 31210\frac{31}{210}, oltre a 110\frac1{10} per ciascuno dei 1010 tagli di C5C_5 e 15\frac15 per i 44 di K4K_4.

Risultati: C5C_5: 1/101/10 (limite raggiunto); K4K_4: 1/51/5 per taglio, 4/54/5 in totale, t=3t=3; K5K_5: 31/21031/210 per taglio.

python
from fractions import Fraction as F
from functools import lru_cache
from collections import Counter
from itertools import combinations

def esatto(archi):
    """Distribuzione esatta del taglio finale di Karger: {lato che contiene il vertice minimo: probabilita'}."""
    @lru_cache(maxsize=None)
    def rec(stato):                                   # stato: ((A, B), molteplicita') con A, B frozenset
        lati = {x for (a, b), _ in stato for x in (a, b)}
        if len(lati) == 2:
            return {min(lati, key=sorted): F(1)}
        tot = sum(m for _, m in stato)
        out = Counter()
        for (a, b), m in stato:
            nuovo = Counter()
            for (c, d), mm in stato:
                if {c, d} == {a, b}: continue         # il cappo scompare
                c2 = a | b if c in (a, b) else c
                d2 = a | b if d in (a, b) else d
                nuovo[tuple(sorted((c2, d2), key=sorted))] += mm
            for lato, p in rec(tuple(sorted(nuovo.items(), key=lambda kv: [sorted(x) for x in kv[0]]))).items():
                out[lato] += F(m, tot) * p
        return dict(out)
    c = Counter(tuple(sorted((frozenset([u]), frozenset([v])), key=sorted)) for u, v in archi)
    return rec(tuple(sorted(c.items(), key=lambda kv: [sorted(x) for x in kv[0]])))

dim = lambda E, lato: sum((u in lato) != (v in lato) for u, v in E)
for nome, E in (("C5", [(i, i % 5 + 1) for i in range(1, 6)]), ("K4", list(combinations(range(1, 5), 2))),
                ("K5", list(combinations(range(1, 6), 2)))):
    d = esatto(E); k = min(dim(E, l) for l in d)
    minimi = {tuple(sorted(l)): p for l, p in d.items() if dim(E, l) == k}
    print(nome, k, set(minimi.values()), sum(minimi.values()))     # C5 {1/10} 1;  K4 {1/5} 4/5;  K5 {31/210} 31/42

Versione ripasso

Teoria collegata