Esercizio - Probabilità esatte di Karger sul ciclo e sul grafo completo
Testo. Si considera l'algoritmo di contrazione di Karger.
- Sul ciclo (vertici , archi ) calcolare la probabilità che esca un taglio minimo specifico, per esempio la coppia . Confrontarla col limite .
- Sul grafo completo calcolare la probabilità che esca il taglio (vertice da solo) e quella che esca un taglio minimo qualunque.
- Quante esecuzioni indipendenti servono su per fallire con probabilità ? Quante darebbe il limite generale?
- (Verifica con un programma) Probabilità esatte su .
Soluzione
Punto 1. Nel ciclo ogni vertice ha grado e, dopo ogni contrazione, il grafo resta un ciclo (più corto) che ha vertici e archi. Il taglio minimo vale e in ogni passo : la disuguaglianza della dimostrazione è un'uguaglianza. Quindi la probabilità di non scegliere un arco di al passo vale esattamente (e il taglio specifico è un taglio minimo del ciclo contratto). I passi sono : Il limite è raggiunto: nel ciclo è la probabilità esatta di ciascuno dei tagli minimi (le coppie di archi), e la somma è : l'output è sempre un taglio minimo.
Punto 2. In ogni vertice ha grado , , , il limite è . Per ottenere non si deve mai contrarre un arco incidente a .
- Primo passo: archi, incidenti a : si evita con . Si contrae, per esempio, : nasce .
- Secondo passo: il multigrafo ha vertici e archi (doppio: , ), (doppio: , ), (singolo): archi. Si evita solo contraendo : probabilità .
- Alla fine restano e , con archi: il taglio .
Per simmetria vale lo stesso per ciascuno dei tagli a vertice singolo (i soli tagli minimi, di dimensione ); i tagli hanno archi. Probabilità di un taglio minimo qualunque: . Si verifica anche direttamente: all'ultimo passo, con vertici e archi , il taglio finale ha dimensione se si contrae o () e dimensione se si contrae ().
Punto 3. Un'esecuzione fallisce (non trova un taglio minimo) con probabilità . Serve , , quindi (). Il limite generale darebbe .
Punto 4. In ogni vertice ha grado , quindi e i tagli minimi sono i cinque a vertice singolo (un taglio ha archi). A mano, per il taglio :
- primo passo: archi, incidenti a , si evita con ; per simmetria si contrae e nasce ;
- secondo passo: archi doppi e singoli, in tutto; quelli che non toccano sono (), (), ();
- terzo passo, se si è contratto (probabilità ): nasce con archi verso , verso e l'arco , archi; si evita solo con i verso : . Lo stesso se si è contratto ();
- terzo passo, se si è contratto (): nasce con archi verso , mentre ha archi verso e altri : su archi, evitano , cioè .
Un taglio minimo qualunque esce con . Il programma sotto enumera tutte le sequenze di contrazioni con le frazioni e conferma , oltre a per ciascuno dei tagli di e per i di .
Risultati: : (limite raggiunto); : per taglio, in totale, ; : per taglio.
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/42Versione ripasso
- Ciclo : , , cioè con uguaglianza: probabilità di evitare esattamente . Prodotto : limite raggiunto; ognuno dei tagli esce con (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 →).
- : , limite . Per il taglio : primo passo evitare con ; poi vertici con archi , serve : . Totale . Quattro tagli minimi, quindi ; il taglio (dimensione ) esce con .
- Ripetizioni su per : ; limite generale .
- Perché nel ciclo il limite è esatto: contrarre un arco di un ciclo dà un ciclo con un vertice in meno, quindi ogni passo ha archi e grado ovunque; alla fine restano due archi paralleli, cioè l'output è sempre un taglio minimo e le probabilità sommano a .
- a mano, taglio : ; primo passo ; poi archi ( doppi, singoli); con o () restano archi e si evita con , con () restano archi e si evita con . Totale per taglio, in totale (confermato dall'enumerazione con frazioni).
- Errori tipici: dimenticare che gli archi paralleli contano come archi distinti nella scelta; credere che sia sempre la probabilità esatta (lo è solo per il ciclo).