Salta al contenuto
Note per Studenti Esercizio - Numero di tagli minimi di un grafo, dimostrazione e casi estremi

Esercizio - Numero di tagli minimi di un grafo, dimostrazione e casi estremi

Testo (domanda da orale).

  1. Dimostrare che un multigrafo con nn vertici ha al più (n2)\binom n2 tagli minimi.
  2. Dire quale grafo raggiunge il limite e contare i tagli minimi di: il ciclo C6C_6; il cammino con 66 vertici; la stella con centro e 55 foglie; il grafo completo K5K_5; il grafo bipartito completo K3,3K_{3,3}; i due triangoli collegati da un ponte (66 vertici).
  3. Verificare i conteggi enumerando tutte le bipartizioni.

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 → (corollario sul numero di tagli minimi).

Soluzione

Punto 1. Sia kk il taglio minimo e siano C1,…,CrC_1,\dots,C_r i tagli minimi distinti. Per il teorema di Karger, l'algoritmo restituisce proprio CjC_j con probabilità pj≥2n(n−1)=1/(n2)p_j\ge\frac2{n(n-1)}=1/\binom n2. Gli eventi «l'output è CjC_j» sono a due a due disgiunti (l'output è un solo taglio). Quindi 1≥∑j=1rpj≥r(n2)⟹r≤(n2).1\ge\sum_{j=1}^rp_j\ge\frac r{\binom n2}\quad\Longrightarrow\quad r\le\binom n2 . Il risultato dice che, anche se i tagli possibili sono 2n−1−12^{n-1}-1, quelli minimi sono pochi.

Punto 2. Il limite è raggiunto dal ciclo, che ha (n2)\binom n2 tagli minimi (le coppie di archi), tutti di dimensione 22; gli altri grafi dell'elenco ne hanno molti meno.

  • C6C_6: (62)=15\binom62=15 tagli minimi, di dimensione 22 (uno per ogni coppia di archi).
  • Cammino con 66 vertici: ha 55 archi, ognuno è un ponte e un taglio di dimensione 11: 55 tagli minimi (≤15\le15).
  • Stella con 55 foglie: 55 tagli minimi (uno per foglia, dimensione 11).
  • K5K_5: il grado è 44, il taglio minimo è 44 e sono minimi i tagli a vertice singolo: 55 tagli (≤10\le10). Un taglio 2+32+3 ha 66 archi.
  • K3,3K_{3,3}: grado 33, taglio minimo 33, tagli a vertice singolo: 66 tagli (≤15\le15).
  • Due triangoli con ponte: il ponte è l'unico taglio di dimensione 11: 11.

In generale un albero con nn vertici ha n−1n-1 tagli minimi (uno per arco, ciascuno un ponte).

Punto 3. Enumerando le 2n−1−12^{n-1}-1 bipartizioni (con l'ultimo vertice sempre nel lato 0) e contando gli archi tagliati, un programma trova: C6C_6: dimensione 22 e 1515 tagli; cammino: 11 e 55; stella: 11 e 55; K5K_5: 44 e 55; K3,3K_{3,3}: 33 e 66; due triangoli: 11 e 11. Per K4K_4: 33 e 44.

Risultati: limite (n2)\binom n2 dimostrato con eventi disgiunti; 15, 5, 5, 5, 6, 115,\ 5,\ 5,\ 5,\ 6,\ 1 nell'ordine dell'elenco; il ciclo raggiunge il limite.

python
from itertools import combinations
def tagli_minimi(n, E):
    miglior, conteggio = None, 0
    for m in range(1, 2**(n - 1)):                    # il vertice n-1 resta sempre nel lato 0
        d = sum(((m >> u) & 1) != ((m >> v) & 1) for u, v in E)
        if miglior is None or d < miglior: miglior, conteggio = d, 1
        elif d == miglior: conteggio += 1
    return miglior, conteggio
ciclo = [(i, (i + 1) % 6) for i in range(6)]
print(tagli_minimi(6, ciclo))                                                     # (2, 15)
print(tagli_minimi(6, [(i, i + 1) for i in range(5)]))                            # (1, 5)
print(tagli_minimi(6, [(0, i) for i in range(1, 6)]))                             # (1, 5)
print(tagli_minimi(5, list(combinations(range(5), 2))))                           # (4, 5)
print(tagli_minimi(6, [(a, b) for a in range(3) for b in range(3, 6)]))           # (3, 6)
print(tagli_minimi(6, [(0, 1), (0, 2), (1, 2), (3, 4), (3, 5), (4, 5), (2, 3)]))  # (1, 1)

Versione ripasso

Teoria collegata