Correctness of Dijkstra je žebříček důkazů #2: prokazatelně padla minimálně ve dvou termínech (02.06.2021 a zkoušky 2023) a zadává se vždy stejně — pseudokód + „Prove the correctness“. Běh Dijkstry už umíš z [L2.4] Dijkstrův algoritmus (běh) a nebudeme ho vykládat znovu: vyber neuzavřený vrchol s nejmenší značkou, uzavři, relaxuj odchozí hrany [L2.3]. Dnes jde o otázku PROČ to funguje — tedy o důkaz, který v písemce odevzdáš celý, na papír, vlastní rukou.
Po skončení má pro každý vrchol $v$ platit $l(v) = \mathrm{dist}(v)$, kde $\mathrm{dist}(v)$ je skutečná délka nejkratší cesty $s \to v$ (a $l(v) = \infty$ právě pro nedosažitelné vrcholy). Vektor $p$ má navíc kódovat strom nejkratších cest.
Přímo „po skončení“ se to ale dokazuje špatně. Trik (a jediná nová věc téhle lekce): dokážeme silnější průběžné tvrzení — invariant, který platí po celou dobu běhu. Silnější tvrzení se indukcí často dokazuje snáz, protože máš silnější indukční předpoklad.
Domluvme značení podle vzorového řešení (banka úloh): $D(v)$ je aktuální Dijkstrova značka (v pseudokódu $l(v)$ — přeznačení jen odlišuje „co tvrdí algoritmus“ od pravdy), $\mathrm{dist}(v)$ je skutečná nejkratší vzdálenost z $s$ do $v$ a $R$ je množina uzavřených (finalized) vrcholů. Pro $v \notin R$ je $D(v)$ definované, ale jen pracovní (tentative) [L2.4].
Dokazujeme indukcí přes velikost $R$: každá iterace while-cyklu přidá do $R$ právě jeden vrchol, takže „indukce přes $|R|$“ = „indukce přes iterace algoritmu“. Když invariant přežije všechny iterace, na konci je $R = V(G)$ a všechny značky jsou správně — přesně korektnost.
První iterace vybere vrchol s nejmenší značkou — po inicializaci je to $s$ (jediný s $l = 0$, ostatní $\infty$).
Prázdná cesta z $s$ do $s$ má délku $0$, takže $\mathrm{dist}(s) \le 0$. A kratší to být nemůže, protože všechny váhy jsou nezáporné — každý sled má délku $\ge 0$. Tady poprvé (a zatím nenápadně) vstupuje předpoklad $c : E(G) \to \mathbb{R}^+_0$: kdyby přes $s$ vedl záporný cyklus, bylo by „$\mathrm{dist}(s) = -\infty$“ a báze by spadla hned [L2.1].
Báze hotova: $D(s) = 0 = \mathrm{dist}(s)$, invariant pro $R = \{s\}$ platí.
Indukční předpoklad: invariant platí, všechny vrcholy v $R$ mají správné vzdálenosti. Algoritmus teď vybírá nejlepšího kandidáta
$$v \in V \setminus R, \qquad D(v) = \min_{z \in V \setminus R} D(z)$$a chce ho uzavřít. Musíme dokázat, že $D(v) = \mathrm{dist}(v)$. Rovnost rozdělíme na dvě nerovnosti — jedna je skoro zadarmo, druhá je jádro důkazu.
Konečná značka vzniká jedině relaxací: někdy dříve se uzavíral nějaký vrchol $x \in R$ a vnitřní smyčka nastavila $D(v) := D(x) + c(x,v)$, $p(v) := x$. Po řetízku předchůdců $p$ zpátky až do $s$ to znamená, že $D(v)$ je délka skutečného existujícího sledu $s \to \cdots \to x \to v$ [L2.3]. Nejkratší cesta nemůže být delší než nějaký konkrétní sled, tedy $\mathrm{dist}(v) \le D(v)$.
(Okrajový případ $D(v) = \infty$: pak mají $\infty$ všechny vrcholy mimo $R$. Všechny hrany vedoucí z $R$ ven už ale relaxovány byly — kdyby nějaká existovala, její konec by měl konečnou značku. Žádná tedy neexistuje, vrcholy mimo $R$ jsou nedosažitelné a $\mathrm{dist} = \infty = D$ sedí. Banka i slidy tento případ přecházejí mlčky; u písemky stačí věta v závorce.)
Zbývá $D(v) \le \mathrm{dist}(v)$, tedy: žádná cesta $s \to v$ není kratší než $D(v)$. Důkaz povedeme sporem: předpokládejme, že existuje $s$–$v$ cesta $P$ s
$$|P| < D(v).$$$P$ musí někde poprvé opustit množinu $R$. Označme $y$ první vrchol na $P$, který neleží v $R$, a $x$ jeho předchůdce na $P$. Z definice „první“ plyne $x \in R$ — a na $x$ se proto vztahuje indukční předpoklad: $D(x) = \mathrm{dist}(x)$. (Klidně může být $y = v$, pokud $P$ vede až do $v$ celou dobu uvnitř $R$ — argument níže funguje beze změny.)
Když byl $x$ přidán do $R$, vnitřní smyčka otestovala všechny jeho odchozí hrany do neuzavřených vrcholů — tedy i hranu $(x,y)$. Po této relaxaci platí (a značky už nikdy nerostou, takže platí pořád):
$$D(y) \;\le\; D(x) + c(x,y) \;=\; \mathrm{dist}(x) + c(x,y) \;\le\; |P[s,x]| + c(x,y) \;=\; |P[s,y]|,$$kde $P[s,x]$ je úsek cesty $P$ od $s$ do $x$. Prostřední nerovnost: $P[s,x]$ je nějaká $s$–$x$ cesta, takže není kratší než $\mathrm{dist}(x)$. Slovy: značka prvního vrcholu za hranicí $R$ není horší než délka $P$ až k němu.
Zbytek cesty $P$ od $y$ do $v$ se skládá z hran s váhami $c \ge 0$, takže má délku $\ge 0$ a
$$|P[s,y]| \;\le\; |P|.$$To je celé — jediné místo důkazu, kde nezápornost vstupuje, a přesně to místo, které záporná hrana zboří (viz níže). Složením řetízku:
$$D(y) \;\le\; |P[s,y]| \;\le\; |P| \;<\; D(v).$$A to je spor: $y \notin R$ byl také kandidát na uzavření, ale má ostře menší značku než $v$ — algoritmus by tedy nevybral $v$, vybral by $y$ (nebo někoho ještě lepšího). To odporuje volbě $v$ jako minima. Kratší cesta $P$ tedy neexistuje, $D(v) = \mathrm{dist}(v)$, invariant platí i pro $R \cup \{v\}$ a indukce je hotová. $\blacksquare$
Celý argument si přehraj krok za krokem na schématu (zelené vrcholy = $R$, červeně = hypotetická kratší cesta $P$):
Vrať se k protipříkladu z [L2.4] a podívej se na něj očima důkazu:
Cesta $P$ má $|P| = 0 < 1 = D(a)$, takže podle důkazu by měl existovat spor. Projdi řetízek: první vrchol mimo $R = \{s\}$ na $P$ je $y = b$, předchůdce $x = s$. Odhad značky funguje: $D(b) \le \mathrm{dist}(s) + c(s,b) = 2 = |P[s,b]|$. Jenže další krok
$$|P[s,y]| \le |P| \qquad \text{by znamenalo} \qquad 2 \le 0 \;—\; \text{NEPLATÍ.}$$Zbytek cesty ($b \to a$ s váhou $-2$) má zápornou délku, takže prefix je delší než celá cesta. Spor se nekoná, $D(b) = 2$ je klidně větší než $D(a) = 1$, Dijkstra s čistým svědomím uzavře $a$ se špatnou hodnotou — a hranu $(b,a)$ už nikdy neotestuje, protože vnitřní smyčka jede jen přes $w \notin R$ [L2.4].
Slidy (03_SPT_KO, slide 18–19) vedou indukční krok bez explicitního sporu — ukazují, že pro uzavíraného kandidáta $v$ platí Bellmanova rovnice [L2.2] $\;l(s,v) = \min_{k \ne v} \{\,l(s,k) + c(k,v)\,\}$, rozborem možných předchůdců $k$ na dva případy (EN 1:1):
Je to tentýž argument v jiném kabátě. Případ „$k \in R$“ = naše relaxace hrany $(x,y)$ na hranici (všechny hrany z $R$ ven byly otestovány — proto víme $D(y) \le \mathrm{dist}(x) + c(x,y)$). Případ „$k \notin R$“ = naše nezápornost + minimalita $v$ (cesta procházející vrcholem mimo $R$ nese už aspoň $l(v)$ a nezáporné hrany nic neslevují — přesně řetízek $D(y) \le |P| < D(v)$ obrácený do sporu). U zkoušky si vyber jednu verzi a doveď ji do konce; verze sporem z banky je vzorové řešení a hůř se v ní něco zamlčí.
Indukční kostru „invariant + rostoucí množina / počet iterací“ si zapamatuj — stejné schéma použijeme u korektnosti Bellman-Forda [L3.7], jen invariant poběží přes počet průchodů („po $k$ průchodech je $l(w)$ nejvýš délka nejkratšího sledu o $\le k$ hranách“).
Prove the correctness of Dijkstra's Algorithm.
Input: digraph $G$, weights $c : E(G) \to \mathbb{R}_0^+$ and node $s \in V(G)$.
Output: Vectors $l$ and $p$. For $v \in V(G)$, $l(v)$ is the length of the shortest path from $s$ and $p(v)$ is the previous node in the path. If $v$ is unreachable from $s$, $l(v) = \infty$ and $p(v)$ is undefined.
l(s) := 0; l(v) := ∞ for v ≠ s; R := ∅;
while R ≠ V(G) do
Find v ∈ V(G) \ R such that l(v) = min_{w∈V(G)\R} l(w);
R := R ∪ {v};
// calculate l(w) for all nodes on border of R
for w ∈ V(G) \ R such that (v, w) ∈ E(G) do
if l(w) > l(v) + c(v, w) then
l(w) := l(v) + c(v, w); p(w) := v;
end
end
end
Čistě důkazová úloha: je dán pseudokód Dijkstry (tentýž, co znáš z [L2.4]) a máš dokázat, že po skončení je $l(v)$ skutečně délka nejkratší cesty z $s$ pro každý vrchol (s konvencí $\infty$ pro nedosažitelné). Žádná čísla, žádný konkrétní graf — odevzdává se text důkazu.
Nezačínej psát nerovnosti — začni strukturou: (1) zaveď značení $D$ / $\mathrm{dist}$ / $R$, (2) vyslov invariant, (3) řekni „indukce přes $|R|$“, (4) báze, (5) krok. V kroku rozděl rovnost na snadný směr ($D(v)$ je délka skutečného sledu) a spor (kratší cesta $P$ → první vrchol $y$ mimo $R$ → dva odhady na $D(y)$). Hlídej si dvě věci, na které se u tabule ptají: kde přesně se použila nezápornost a proč byla hrana $(x,y)$ vůbec někdy relaxována.
Značení. $D(v)$ = aktuální Dijkstrova značka (v pseudokódu $l(v)$), definovaná pro každý vrchol; pro $v \notin R$ je jen pracovní. $\mathrm{dist}(v)$ = skutečná nejkratší vzdálenost z $s$ do $v$. $R$ = množina uzavřených (finalized) vrcholů.
Invariant. Dokážeme indukcí přes velikost $R$:
$$\forall u \in R: \quad D(u) = \mathrm{dist}(u).$$Báze. Prvním vybraným vrcholem je $s$ a $D(s) = 0 = \mathrm{dist}(s)$ (váhy jsou nezáporné, takže žádný sled nemá zápornou délku a prázdná cesta délky $0$ je nejkratší).
Indukční krok. Nechť invariant platí a algoritmus vybírá
$$v \in V \setminus R, \qquad D(v) = \min_{z \in V \setminus R} D(z).$$Protože $D(v)$ je délka nějakého známého sledu $s \to v$ (vznikla řetězem relaxací, sled rekonstruuje vektor $p$), platí
$$\mathrm{dist}(v) \le D(v).$$Zbývá ukázat, že kratší cesta neexistuje. Pro spor nechť existuje $s$–$v$ cesta $P$ s $|P| < D(v)$. Nechť $y$ je první vrchol na $P$ s $y \notin R$ a $x$ jeho předchůdce na $P$; pak $x \in R$. Z indukčního předpokladu
$$D(x) = \mathrm{dist}(x) \le |P[s,x]|.$$Když se $x$ uzavíral, hrana $(x,y)$ byla relaxována, a protože značky už jen klesají,
$$D(y) \le D(x) + c(x,y) \le |P[s,x]| + c(x,y) = |P[s,y]|.$$Všechny váhy jsou nezáporné, takže úsek $P$ od $y$ do $v$ má délku $\ge 0$ a
$$|P[s,y]| \le |P|.$$Dohromady
$$D(y) \le |P[s,y]| \le |P| < D(v).$$Jenže $y \notin R$, takže $y$ byl také dostupný kandidát — to je spor s volbou $v$ jako vrcholu s minimální značkou mimo $R$. Žádná cesta kratší než $D(v)$ tedy neexistuje a
$$D(v) = \mathrm{dist}(v).$$Invariant zůstává zachován i po $R := R \cup \{v\}$ a indukcí je Dijkstrův algoritmus korektní. $\blacksquare$
Doplňky pro úplnost (vlastní, banka je neuvádí — u písemky stačí věta):
Krátká zkoušková odpověď (kostra, kterou rozepíšeš): ① značení $D/\mathrm{dist}/R$; ② invariant $\forall u \in R: D(u)=\mathrm{dist}(u)$, indukce přes $|R|$; ③ báze $D(s)=0$; ④ $\mathrm{dist}(v) \le D(v)$ ($D(v)$ = délka skutečného sledu); ⑤ spor: $P$ kratší → první $y \notin R$, předchůdce $x \in R$ → relaxace $(x,y)$ → $D(y) \le |P[s,y]| \stackrel{c \ge 0}{\le} |P| < D(v)$ → spor s minimalitou $v$; ⑥ závěr. Nezápornost výslovně vyznač v kroku ⑤.
Tenhle důkaz napiš celý NA PAPÍR (bez koukání do řešení i do lekce — u zkoušky ho taky píšeš zpaměti) a pošli mi fotku. Zkontroluju strukturu (invariant → báze → krok → spor), úplnost řetízku nerovností a hlavně to, jestli jsi správně vyznačil(a), kde se používá nezápornost hran.