Toky

Max Flow
  • Ford-Fulkerson

  • Capacity Scaling

  • Shortest Augmenting Path

  • Push Relabel

  • Applications

Flow network

Pětice , kde

  • je orientovaný graf,

  • je source (zdroj),

  • je sink (odtok),

  • , kde jsou obvykle nebo , je kapacita hrany .

-řezy

Je rozklad vrcholů na takový, že a .

Kapacita -řezu

Součet kapacit hran na rozhraní a :

-toky

Funkce taková, že:

  • platí kapacitní podmínka: ,

  • platí zachování toku: .

Hodnota toku
Residual network

Síť, která vzniká, když je už část kapacity hrany využívána tokem . Umožnuje algoritmům změnit přechozí rozhodnutí a získat využitou kapacitu zpět.

Je to pětice , kde

  • ,

  • pokud , ,

Augmenting path

Jednoduchá cesta v residuální síti .

Note
T.j. cesta která může jít i proti směru toku .

Bottleneck kapacita je nejmenší kapacita hran v augmenting path .

To krásné na augmenting cestách je, že pro flow a augmenting path v grafu , existuje tok takový, že . Nový tok lze získat takto:

Augment(f, c, P)
{
    delta = bottleneck(P)
    foreach(e in P)
    {
        if(e in E)
        {
            f[e] = f[e] + delta
        }
        else
        {
            f[reverse(e)] = f[reverse(e)] - delta
        }
    }
    return f
}
Max-flow min-cut theorem

Hodnota maximálního toku je rovna kapacitě minimálního řezu.

Ford-Fulkerson vs Goldberg
Ford-Fulkerson Goldberg

global character

local character

update flow along an augmenting path

update flow on edges

flow conservation

preflow

Ford-Fulkersonova metoda (augmenting path method)

  1. pro každou .

  2. Najdi cestu v reziduální síti .

  3. Augmentuj tok podél .

  4. Opakuj dokud se nezasekneš.

Ford–Fulkerson(G)
{
    foreach (e in E)
    {
        f(e) = 0
    }

    G_f = reziduální síť vzniklá z G vzhledem k toku f
    while (existuje s ~> t cesta v G_f)
    {
        f = Augment(f, c, P)
        Updatuj G_f
    }
    return f
}

Goldbergova metoda (push-relabel method)

Pre-flow

Funkce taková, že

  • platí kapacitní podmínka: ,

  • platí relexováné zachování toku: .

Overflowing vertex

Takový vertex , do kterého více přitéká než odtéká.

Excess flow

To, co je v overflowing vertexu navíc.

Height function

Funkce . Řekneme, že je kompatibilní s preflow , právě když

  • source: ,

  • sink: ,

  • height difference: .

    Note
    Pokud mezi dvěma vrcholy v reziduální síti vede hrana, pak je nejvýše o jednu úroveň výš než .
Tip
Lemma

Pokud je preflow a je height function kompatibilní s , pak neexistuje cesta v .

Důkaz

Nejdelší jednoduchá cesta má vrcholů a hran. Z definice plyne (kombinací nerovností) . Protože je z definice 0, pak , což je spor, protože .

Tip
Lemma

Pokud je flow (tedy zejména preflow) a je height function kompatibilní s , pak je maximální tok.

Push operace

Pro (reziduálně-grafovou) hranu se pokusí přesunout excess flow z do , aniž by porušil (reziduální) kapacitu .

// Assumptions: e_f[v] > 0, c_f( (v, w) > 0) > 0, h[v] > h[w]
Push(f, h, v, w)
{
    delta_f = min(e_f[v], c_f(v, w))
    if( (v, w) in E)
        f[(v, w)] += delta_f
    else
        f[(w, v)] -= delta_f
    e_f[v] -= delta_f
    e_f[w] += delta_f
}
Relabel operace

Zvýší výšku natolik, aby neporušil kompatibilitu s .

// Assumptions:
//   - v is overflowing: e_f[v] > 0
//   - all residual neighbors of v the same height or higher: forall (v, w) in E_f: h[v] <= h[w]
Relabel(f, h, v)
{
    h[v] = 1 + min(h[w] | (v, w) in E_f)
}
Generic Push-Relabel
Generic-Push-Relabel(V, E, s, t, c)
{
    // initialize preflow — default values
    for(v in V)
    {
        h[v] = 0    // height function
        e_f[v] = 0  // excess flow
    }
    n = |V|
    h[s] = n

    for(e in E)
    {
        f[e] = 0    // (pre)flow
    }

    // initialize preflow — saturate connections from s
    for( (s, v) in E)
    {
        f[(s, v)] = c(s, v) // preflow maxes out all capacity
        e_f[v] = c(s, v)    // presume all of it excess
        e_f[s] -= c(s, v)   // yes, it will be negative
    }

    // the juicy part
    while(any vertex is overflowing)
    {
        v = an overflowing vertex (has e_f[v] > 0)
        if(v has a neighbor w in G_f such that h(v) > h(w))
        {
            Push(f, h, v, w)
        }
        else
        {
            Relabel(f, h, v)
        }
    }
    return f
}
Amortizovaná složitost Push-Relabel

operací Push nebo Relabel.