if l(w) > l(v) + c(v,w) then l(w) := l(v) + c(v,w); p(w) := v — jediný stavební kámen, ze kterého jsou poskládané všechny algoritmy na nejkratší cesty v této kapitole.
Prerekvizity: [L2.2] Bellmanův princip optimality + Bellmanova rovnice. Tam jsme skončili pozorováním, že Bellmanova rovnice je soustava rovnic svazující neznámé vzdálenosti — a slíbili si, že algoritmy budou různé strategie jejího řešení. Dnes si postavíme jejich společný elementární krok.
Bellmanova rovnice $l(s,w) = \min_{v \ne w}\{\,l(s,v) + c(v,w)\,\}$ mluví o hotových vzdálenostech. Algoritmus je ale na začátku nezná — musí s něčím začít a postupně se k vzdálenostem propracovat.
Jediné, co víme zadarmo: do startu se dostanu prázdnou cestou ($l(s) = 0$) a o ostatních vrcholech nevím nic — žádnou cestu do nich jsem zatím neviděl, takže $l(v) = \infty$ pro $v \ne s$. Přesně tak začínají všechny algoritmy kapitoly (slide 16 i 29):
l(s) := 0; l(v) := ∞ pro v ≠ s;
Hodnotám $l(v)$ se říká labels (značky): jsou to pracovní odhady vzdáleností, ne vzdálenosti samotné. Algoritmus je bude postupně snižovat, dokud se neusadí na správných hodnotách.
Vedle značky $l(v)$ si budeme držet ještě předchůdce $p(v)$ — odkud jsme do $v$ aktuálně nejlevněji přišli. K čemu je, uvidíš za chvíli.
Teď ten klíčový nápad. Mám rozpracované značky a koukám na jedinou hranu $(v,w)$ s váhou $c(v,w)$.
Když se do $v$ umím dostat za $l(v)$, pak prodloužením o hranu $(v,w)$ se do $w$ dostanu za $l(v) + c(v,w)$. Pokud je to méně než můj dosavadní odhad $l(w)$, našel jsem lepší příchod do $w$ — přepíšu značku a zapamatuji si, kudy to šlo: $p(w) := v$. Pokud to méně není, nedělám nic.
To je celé. Tenhle test-a-přepis je přesně člen $l(s,v) + c(v,w)$ z Bellmanovy rovnice, vyhodnocený pro jednu konkrétní hranu na aktuálních odhadech.
if l(w) > l(v) + c(v,w) then
l(w) := l(v) + c(v,w); p(w) := v;
end
Tento krok je doslova (znak po znaku) vnitřní smyčka Dijkstrova algoritmu (slide 16) i Bellman-Fordova algoritmu (slide 29). V literatuře se mu říká relax — hrana $(v,w)$ je „napjatá“ (porušuje nerovnost), relaxací ji „povolíme“.
Prohlédni si jednu relaxaci krok za krokem:
Slidy 16 a 29 popisují výstup algoritmů shodně: vektory $l$ a $p$ — pro $v \in V(G)$ je $l(v)$ délka nejkratší cesty z $s$ a $p(v)$ předchozí vrchol na ní; pro $v$ nedosažitelný z $s$ je $l(v) = \infty$ a $p(v)$ nedefinované.
Couváním: $p(w)$ říká, odkud nejkratší cesta do $w$ přišla; $p(p(w))$ odkud přišla tam; … a tak dál, dokud nedojdu do $s$. Posloupnost pak otočím: $s \to \dots \to p(p(w)) \to p(w) \to w$.
Každý vrchol si pamatuje jen jednoho předchůdce, takže hrany $\{(p(v), v)\}$ dohromady tvoří strom zakořeněný v $s$ — shortest paths tree, SPT (strom nejkratších cest). Jeden vektor $p$ tak kóduje nejkratší cesty do všech vrcholů najednou.
Ne (v grafu bez záporných cyklů). Každá konečná hodnota $l(w)$ vznikla řetězem relaxací $s \to \dots \to w$, takže je to délka skutečného spojení z $s$ do $w$ v grafu. A žádné spojení nemůže být kratší než nejkratší cesta — případné cykly v něm mají váhu $\ge 0$, takže jejich vypuštění délku nezvýší.
Značky se tedy ke vzdálenostem blíží vždy shora: $l(w) \ge l(s,w)$ po celou dobu běhu a relaxace je jen snižují. Otázka je, kdy dolů „dopadnou“ — a na to odpovídá další pozorování.
„Žádná hrana se nedá relaxovat“ znamená, že pro každou hranu $(v,w)$ platí $l(w) \le l(v) + c(v,w)$. Spolu s předchozím pozorováním ($l$ nikdy nepodleze vzdálenosti a každá konečná značka je dosažitelná skutečným spojením) to znamená, že značky splňují Bellmanovu rovnici z [L2.2] — a jsou rovny vzdálenostem. Stav „nic nejde relaxovat“ je tedy cíl výpočtu: relaxace je lokální krok směrem ke splnění Bellmanovy rovnice.
(Tohle je zatím intuice — pořádné důkazy korektnosti Dijkstry a Bellman-Forda patří do kapitoly K3, tady v K2 nás zajímá běh a použití.)
Správné značky dostaneme, ať relaxujeme v jakémkoli pořadí — jen to může trvat různě dlouho. Sleduj na miniaturním řetízku:
Právě strategií pořadí relaxací:
Až je v dalších lekcích uvidíš, hledej v pseudokódu vždy stejné jádro — tenhle if.
if l(w) > l(v) + c(v,w) then l(w) := l(v) + c(v,w); p(w) := v. Inicializace: $l(s) = 0$, $l(v) = \infty$ jinak.Consider the chain of 4 nodes with edges $(1,2)$, $(2,3)$, $(3,4)$ of weights $-2$, $1$, $2$. Find the shortest paths tree from node $1$ by repeated passes in which every edge of the graph is relaxed. Assuming the edges to be processed (i) in the worst order, from right to left, and (ii) in the best order, from left to right — how many passes over all edges does each ordering require to obtain the shortest paths tree?
Řetízek $1 \to 2 \to 3 \to 4$. Opakovaně projíždíme všechny tři hrany a relaxujeme; ptáme se, kolik průchodů je potřeba, když hrany v průchodu bereme zprava doleva (nejhorší pořadí), a kolik, když je bereme zleva doprava (nejlepší pořadí).
Veď si vektor $l = (l(1), l(2), l(3), l(4))$ a v každém průchodu poctivě otestuj všechny tři hrany v zadaném pořadí. Klíčové pozorování: relaxace $(v,w)$ něco udělá, jen když už $l(v)$ je konečné — informace se šíří od startu „po směru“ hran. Co se stane, když hrany testuju proti směru šíření?
(i) Nejhorší pořadí — zprava doleva: v každém průchodu testujeme $(3,4)$, $(2,3)$, $(1,2)$. Init $l = (0, \infty, \infty, \infty)$.
(ii) Nejlepší pořadí — zleva doprava: $(1,2)$: $l(2):=-2$; hned poté $(2,3)$: $l(3):=-1$; hned poté $(3,4)$: $l(4):=1$. Kroky a), b), c) proběhnou všechny v 1 průchodu.
V obou případech vyjde týž výsledek $l = (0,-2,-1,1)$, $p = (-, 1, 2, 3)$ — pořadí nemění výsledek, jen počet průchodů. Informace teče od startu po hranách: pořadí „proti proudu“ posune frontu poznání o jediný vrchol za průchod. Přesně tahle úvaha za chvíli dá Bellman-Fordovi [L2.12] jeho hranici $n-1$ průchodů — a chytrá volba pořadí je celý trik Dijkstry [L2.4] a SP v DAG [L2.13].
Krokovaná verze řešení (pozor, spoiler — nejdřív si to zkus na papír):
Consider the digraph with nodes $s$, $a$, $b$, $c$ and edges $(s,a)$, $(s,b)$, $(a,b)$, $(a,c)$, $(b,c)$ with weights $1$, $4$, $2$, $5$, $1$. The vectors $l$ and $p$ currently hold $l(s)=0$, $l(a)=1$, $l(b)=4$, $l(c)=6$ and $p(a)=s$, $p(b)=s$, $p(c)=a$.
(i) Which edges can still be relaxed, i.e. satisfy $l(w) \gt l(v) + c(v,w)$? (ii) Perform relaxations until no edge can be relaxed and give the final vectors $l$ and $p$. (iii) Use the vector $p$ to reconstruct the shortest $s$–$c$ path.
Rozpracovaný výpočet: značky $l$ a předchůdci $p$ uprostřed běhu. Máme (i) najít hrany, které ještě jdou relaxovat, (ii) dorelaxovat do stavu, kdy už nic nejde (= Bellmanova rovnice platí, značky jsou vzdálenosti), a (iii) z vektoru $p$ vyčíst nejkratší cestu do $c$.
Projdi všech pět hran a u každé spočti $l(v) + c(v,w)$ vs. $l(w)$ — pozor, test je ostrý (rovnost nestačí). Po každé provedené relaxaci se situace mění, takže hrany, které dřív neprošly testem, otestuj znovu. U (iii) začni v $c$ a couvej.
(i) Test všech hran na stavu $l = (0, 1, 4, 6)$:
(ii) Relaxuj $(a,b)$: $l(b) := 3$, $p(b) := a$. Tím se změnil vstup hrany $(b,c)$ — otestuj znovu: $6 \gt 3+1 = 4$ → relaxuj: $l(c) := 4$, $p(c) := b$. Další kolo testů: $(s,a)$ rovnost, $(s,b)$: $3 \gt 4$? ne, $(a,b)$ rovnost, $(a,c)$: $4 \gt 6$? ne, $(b,c)$ rovnost — nic nejde relaxovat. Finální stav:
$$l = (l(s), l(a), l(b), l(c)) = (0,\, 1,\, 3,\, 4), \qquad p(a) = s,\; p(b) = a,\; p(c) = b.$$
(Kdybychom v (ii) začali hranou $(b,c)$, dostali bychom dočasně $l(c)=5$ — a po relaxaci $(a,b)$ by hrana $(b,c)$ prošla testem znovu: $5 \gt 3+1$. Výsledek je stejný, jen o krok později — pořadí mění průběh, ne výsledek, přesně jako v T01.)
(iii) Couvání z $c$: $p(c) = b$, $p(b) = a$, $p(a) = s$ → otočením dostaneme nejkratší cestu $s \to a \to b \to c$ s délkou $1 + 2 + 1 = 4 = l(c)$ ✓. Hrany $(s,a), (a,b), (b,c)$ jsou zároveň strom nejkratších cest (SPT) z $s$.