Definice: Množinový systém je , kde jsou konečné množiny. Definice: systém různých reprezentantů (SRR) je funkce splňující:
- , tedy z každé množiny systému volí reprezentanta
- je prostá, tedy nezvolí dvakrát stejného reprezentanta Definice: Incidenční graf je na vrcholech , kde hrana je když .
Pozorování: má SRR, právě tehdy když jeho incidenční graf má párování velikosti . Tedy tak , tedy hledáme takovou .
Věta: (Hallova): Systém různých reprezentantů existuje . Důkaz: (SSR Hallova podmínka) Zvolíme-li libovolnou , pak platí, že , tak že prvky jsou vzájemně různé, díky prostosti funkce . Takže platí
(SSR Hallova podmínka) Vezmeme incidenční graf a rozšíříme ho o zdroj jako souseda vrcholů a stok jako souseda vrcholů a orientuji hrany směrem , s jednotkovými kapacitami. V síti nalezneme minimální řez , b.ú.n.o. neobsahuje žádné hrany mezi a (nahraditelné předcházející, či následující). Vezmeme a . Pozorování: Mezi a nevede žádná hrana, jinak by nebyl řez. Na základě pozorování, tedy hrany z vedou výhradně do . Hallova podmínka nám pro dává .
Dle minimaxové věty máme velikost toku . Ale žádný tok nemůže být větší protože bychom potřebovali více hran než jich vede ze zdroje , tedy by vznikal spor s minimalitou řezu. A tedy tok má velikost a definuje nám párování.
Polynomální algoritmus pro nalezení Systému různých reprezentantů (SRR)
Cíl: Mějme kolekci konečných množin , kde každé (univerzum prvků).
Chceme efektivně (polynomiálně) rozhodnout, zda existuje systém různých reprezentantů (tzn. z každé vybrat právě jeden prvek tak, aby žádné dva vybrané byly stejné), a v případě kladného výsledku system i konstrukčně získat.
1. Transformace na bipartitní párování
-
Definice bipartitního grafu :
- Vrcholová množina : indexy množin
- Vrcholová množina : univerzum (podmnožina )
- Hrany :
Každá hrana spojuje „množinu“ s „potencionálním reprezentantem“ .
-
Interpretace: Hledáme tzv. perfektní (resp. úplné) párování (párování) z do .
- párování je množina hran taková, že žádné dva různé páry v nesdílejí vrchol (tj. žádný vrchol je v několika hranách z ).
- Perfektní párování relativně vůči znamená: každé je „spárováno“ právě s jedním prvkem z .
- Pokud existuje párování velikosti , pak z každé množiny bereme právě ten prvek , který je spojen hraničkou . Tím dostaneme SRR.
-
Závěr: Problém “existuje SRR pro ” se redukuje na standardní problém bipartitního párování:
Najít párování velikosti mezi vrcholy a v bipartitním grafu .
Pokud takový párování existuje, odpovídá právě potřebnému systému různých reprezentantů.
2. Algoritmus Hopcroft–Karp (pro maximální bipartitní párování)
Nejčastěji se v praxi používá pro bipartitní grafy Hopcroft–Karpův algoritmus, který má časovou složitost
Postup:
-
Inicializace
- Označíme si struktury:
- pro každý („není dosud spárováno“).
- pro každý .
- pro . (Pomocné pole pro „vrstvy“ v BFS.)
- Označíme si struktury:
-
Fáze BFS (vrstevnicový průchod)
- Vytvoříme frontu . Pro každé :
- Pokud (volné), nastav a .
- Jinak .
- Úroveň „NIL“ (virtuální) nastavíme .
- Klasický BFS:
while Q není prázdná: i = Q.pop() if dist[i] < dist[NIL]: for každé y ∈ Adj[i]: # prohrany (i,y) pokud pairV[y] = –1: dist[NIL] = dist[i] + 1 jinak: if dist[ pairV[y] ] = ∞: dist[ pairV[y] ] = dist[i] + 1 Q.push( pairV[y] )
- Cílem je najít nejkratší vzdálenost z nějakého volného vrcholu do NIL pomocí střídání hran (alternating paths).
- Vytvoříme frontu . Pro každé :
-
Fáze DFS (hledání augmentačních cest)
- Pro každé volné (takové, že ), zkusíme rekurzivně:
function DFS(i): if i ≠ NIL: for každé y ∈ Adj[i]: pokud pairV[y] = –1 nebo (dist[ pairV[y] ] = dist[i] + 1 a zároveň DFS( pairV[y] ) == true): pairV[y] = i pairU[i] = y return true # pokud se nepovedlo najít augmentační cestu z i: dist[i] = ∞ return false return true # když i = NIL
- Po dokončení DFS pro všechna volná máme nalezeny všechny augmentační cesty dané délky.
- Pro každé volné (takové, že ), zkusíme rekurzivně:
-
Opakování
- Dokud BFS najde, že „NIL“ je dosažitelné (tj. ), opakujeme DFS pro každý volný .
- Po vyčerpání augmentačních cest dané délky, spustíme znovu BFS, abychom našli další nejkratší augmentační cesty, atd.
- Proces končí, když BFS už nenajde žádnou augmentační cestu (tj. ).
-
Výsledek
- Po skončení máme sloupec definovaný pro takové , které jsou spárovány.
- Velikost párování je počet , pro které . Pokud je pak existuje perfektní párování přesně z , a tedy i SRR.
- Pokud je velikost méně než , SRR neexistuje.
3. Pseudokód (zjednodušeně)
function HopcroftKarp(G):
for i in X:
pairU[i] = –1
for v in Y:
pairV[v] = –1
párování = 0
while BFS():
for each i in X do:
if pairU[i] = –1: # i je volné
if DFS(i) = true:
párování = párování + 1
return párování