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í:

  1. , tedy z každé množiny systému volí reprezentanta
  2. 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í

  1. 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“ .

  2. 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.
  3. 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:

  1. Inicializace

    • Označíme si struktury:
      • pro každý („není dosud spárováno“).
      • pro každý .
      • pro . (Pomocné pole pro „vrstvy“ v BFS.)
  2. 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).
  3. 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.
  4. 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. ).
  5. 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í