Prerekvizity: [L2.4] Dijkstrův algoritmus (běh). Tam jsme si u běhů opakovaně všímali, že se vrcholy uzavírají v pořadí neklesajících značek — dnes ten slíbený postřeh povýšíme na pracovní nástroj a vytěžíme z něj celou zkouškovou úlohu Edge costs assignment (přiřazení cen hran).
Dijkstra v každé iteraci uzavře neuzavřený vrchol s nejmenší značkou. Protože uzavřená značka už nikdy neklesne a nové odhady vznikají jen přičítáním nezáporných vah k už uzavřeným značkám, uzavírají se vrcholy v pořadí neklesajících $l$ — viz [L2.4]. Pořadí expanze tedy není žádná nezávislá informace „navíc“: je svázané s hodnotami vzdáleností.
Ano — stačí vrcholy seřadit podle výsledné značky: $0, 1, 3, 4, 6, 7, 9, \infty$ dává pořadí $1, 3, 5, 2, 4, 6, 7, 8$. Přesně to vyšlo i krokováním běhu.
Funguje to ale jednoznačně jen tehdy, když jsou všechny značky navzájem různé. Při rovnosti dvou značek pořadí z vektoru $l$ nepoznáš — a jak hned uvidíme, nepozná ho jednoznačně ani sám algoritmus.
Druhá ingredience dneška je nenápadný detail pseudokódu ze slidu 16: vnitřní smyčka relaxuje jen hrany for w ∈ V(G) \ R. Hrana $(v,w)$ se testuje jedinkrát za celý běh — při expanzi $v$ — a pokud je v tu chvíli $w$ už uzavřené, přeskočí se bez testu. Přesně tohle v [L2.4] položilo Dijkstru na záporné hraně: hranu $(b,a)$ vedoucí do uzavřeného vrcholu už nikdo netestoval. Dnes stejný jev využijeme pozitivně. Proklikej si běh a sleduj hranu $b \to a$:
Vůbec nic. Až do expanze $b$ je běh s váhou $1$, $6$ i $100$ identický — váha $b \to a$ do té doby v ničem nefiguruje. A při expanzi $b$ je $a$ už uzavřené, takže smyčka hranu přeskočí, ať na ní stojí cokoliv. Zbytek běhu je zase identický.
Váha takové hrany je pro běh neviditelná: můžeš ji změnit na libovolnou hodnotu a pořadí expanze, vektor $l$ i vektor $p$ vyjdou stejně. (Stejně neviditelné jsou hrany vycházející z posledního uzavřeného vrcholu — při jeho expanzi už žádný neuzavřený $w$ nezbývá.)
Pozor na jemnost: hrana, která se testuje, ale nikdy žádnou značku nesníží (test ostře nevyjde), úplně volná není. Zvětšovat ji můžeš libovolně, ale zmenšit jen po určitou mez — pod ní by začala vyhrávat relaxace a běh by se změnil. Taková hrana má jen povolené rozmezí.
Řádek Find v ∈ V(G) \ R such that l(v) = min… ze slidu 16 neříká, kterého kandidáta vybrat, když je minimálních značek víc. Pravidlu, kterým se implementace při takové remíze rozhodne (např. „vezmi vrchol s nejmenším indexem“), se říká tie-breaking (rozhodování remíz) — a pseudokód žádné nepředepisuje.
Po expanzi $s$ je $l(a) = l(b) = 1$ — remíza. Podle tie-breaku se běh větví:
Výsledný vektor $l = (0, 1, 1, 2)$ vyjde v obou větvích stejně — vzdálenosti jsou pro nezáporné váhy jednoznačné. Liší se ale pořadí expanze a dokonce i množina testovaných (a tedy neviditelných) hran.
Proto když zkouškové zadání říká, že Dijkstra „must visit/expand the vertices in the following order“, znamená to: pořadí musí vyjít při každém tie-breaku — tvoje váhy musí zařídit, aby v okamžiku každého výběru bylo minimum jediné (samé ostré nerovnosti, žádná remíza).
Teď úlohu otočíme — přesně tak je postavená zkoušková úloha Edge costs assignment. Zadané je pořadí expanze, výsledná nejkratší cesta a strop na její cenu; hledají se váhy. Recept:
Consider the graph above. Assign edge weights from $\mathbb{N} = \{1, 2, \dots\}$ to each edge so that (multiple edges can be assigned the same weight):
After you assigned the edge weights such that conditions 1–3 hold, mark the edges whose value can be changed to any value from $\mathbb{N}$ such that a run of Dijkstra algorithm still necessarily results in satisfying conditions 1–3.
Tuhle úlohu vyřeš celou NA PAPÍR — od prázdného listu, bez koukání do lekce ani do řešení, ideálně na čas (na zkoušce na ni budeš mít zhruba 15–20 minut; je za 7 bodů). Pak mi pošli fotku — zkontroluju ti ji a vytknu chyby přesně jako hodnotitel.
Orientovaný graf s vrcholy $s, a, b, c, d, t$ a osmi hranami bez vah — váhy z $\mathbb{N}$ navrhuješ ty. Úloha má dvě části: ① přiřadit váhy tak, aby Dijkstra ze $s$ expandoval přesně v pořadí $s, b, d, a, c, t$, výsledná nejkratší cesta byla $s\!-\!a\!-\!t$ a její cena nejvýš $5$; ② u hotového přiřazení označit hrany, které lze přepsat na libovolnou hodnotu z $\mathbb{N}$, aniž by se podmínky 1–3 mohly rozbít (slovo necessarily: musí to vyjít při každém tie-breaku).
Jdi přesně podle receptu z výkladu. Pořadí $s, b, d, a, c, t$ znamená ostře rostoucí značky $0 = l(s) < l(b) < l(d) < l(a) < l(c) < l(t)$, a podmínka 3 přidává $l(t) \le 5$ — takže se nabízí rovnou $0, 1, 2, 3, 4, 5$. Pak si rozmysli, kdo komu značku doručí: jediná hrana do $b$ je $s \to b$, do $d$ vedou tři, ale v okamžiku uzavření $d$ je z nich expandované jen $b$… Podmínka 2 říká, že $l(t)$ musí doručit hrana $a \to t$ (tj. $p(t) = a$), s cenou cesty $c(s,a) + c(a,t) = l(t)$. Nakonec prověř hrany mimo strom: jak velké musí být $c(d,t)$, aby relaxace z $d$ cestu $s\!-\!a\!-\!t$ nepodlezla ani neremizovala? A volné hrany hledej podle pravidla z výkladu: které hrany vedou do vrcholu, jenž se uzavře dřív, než se expanduje jejich začátek?
① Návrh značek. Pořadí $s, b, d, a, c, t$ + strop $5$ → zvol $l(s)=0$, $l(b)=1$, $l(d)=2$, $l(a)=3$, $l(c)=4$, $l(t)=5$.
② Stromové hrany (kdo značku doručí): $l(b)$ jedině hranou $s \to b$ → $c(s,b)=1$. $l(d)$ může v čase uzavření $d$ doručit jen $b$ → $c(b,d) = 2-1 = 1$. $l(a)$ jedině hranou $s \to a$ → $c(s,a)=3$. $l(c)$ jedině hranou $b \to c$ → $c(b,c) = 4-1 = 3$. $l(t)$ musí kvůli podmínce 2 doručit $a \to t$ → $c(a,t) = 5-3 = 2$; cena cesty $3+2 = 5 \le 5$ ✓.
③ Zbylé hrany nesmí škodit. Hrana $d \to t$ se testuje při expanzi $d$ (3. iterace) a nastaví $l(t) = 2 + c(d,t)$. Aby pak relaxace $a \to t$ ještě ostře vyhrála ($2 + c(d,t) > 3 + 2 = 5$), musí být $c(d,t) \ge 4$. Menší hodnoty selžou:
Zvolíme tedy např. $c(d,t) = 4$. Hrany $a \to d$ a $c \to d$ běh nikdy netestuje (viz ⑤), jejich hodnota je libovolná — pro konkrétnost třeba $1$.
Jedno platné přiřazení (shodné s bankou):
$$c(s,a)=3,\quad c(s,b)=1,\quad c(a,t)=2,\quad c(b,d)=1,\quad c(b,c)=3,\quad c(d,t)=4,$$
a $c(a,d) = x$, $c(c,d) = y$ libovolné ($x, y \in \mathbb{N}$).
④ Ověření během (každý výběr má jediné minimum → pořadí platí pro každý tie-break):
Pořadí expanze $s, b, d, a, c, t$ ✓ (značky $0,1,2,3,4,5$ ostře rostou); couváním po $p$: $p(t)=a$, $p(a)=s$ → cesta $s\!-\!a\!-\!t$ ✓ s cenou $3+2 = 5 \le 5$ ✓.
⑤ Volné hrany. $d$ se uzavírá ve 3. iteraci — dřív, než se expanduje $a$ (4. it.) i $c$ (5. it.). Hrany $a \to d$ a $c \to d$ proto vnitřní smyčka (for w ∈ V(G) \ R) nikdy netestuje a běh je na jejich hodnotě nezávislý:
$$\boxed{a \to d \quad\text{a}\quad c \to d}$$
Žádná další hrana volná není: $c(s,b)$, $c(b,d)$, $c(s,a)$, $c(b,c)$, $c(a,t)$ určují značky (jejich změna posune pořadí nebo cenu cesty) a $c(d,t)$ je svázané mezí $c(d,t) \ge 4$ — viz ③ (to je přesně polopravda z červeného boxu: $d \to t$ na nejkratší cestě neleží, a přesto volné není).
Krokovaná verze ověřovacího běhu (pozor, spoiler na řešení — nejdřív si úlohu vyřeš na papír):