DIMA - Teorie grafů



Dijkstrův algoritmus

Teorie

Hledání nejkratší cesty z daného vrcholu do ostatních vrcholů v nezáporně hranově ohodnoceném grafu

Dijkstrův algoritmus je nejrychlejší známý algoritmus pro nalezení všech nejkratších cest ze zadaného uzlu do ostatních uzlů grafu, který neobsahuje hrany záporné délky.

Vzpomeňme si na Jarníkův algoritmus.

Předpokládejme, že jednotlivá ohodnocení hran v daném grafu odpovídají vzdálenostem mezi vrcholy daného grafu a uvažujme modifikaci: V každém kroku udržujeme pro každý vrchol x, který neleží v modrém stromu, aktuální informaci udávající nejkratší vzdálenost mezi vrcholem x a počátečním vrcholem v.

Touto modifikací dostáváme Dijkstrův algoritmus pro nalezení nejkratší cesty mezi daným vrcholem v a ostatními vrcholy v hranově nezáporně ohodnoceném grafu, který E.W.Dijkstra navrhl a popsal v roce 1950 v práci “A note on two problems in connection with graphs, Numer. Math.,1, 1959, pp. 269-271”.

Ilustrace obou algoritmů, Jarníkova a Dijkstrova

Budeme používat stejný graf, jako v případech pro hledání minimální kostry a to především pro ilustraci podobnosti s Jarníkovým algoritmem

minimální kostra

Jarníkův algoritmus - nalezení minimální kostry

 abcdefghijk
a 1722       
b1 2        
c72   30     
d22    1116    
e     316    
f  301131 1835  28
g   16618     
h     35  824 
i       8 13 
j       2413 5
k     28   5 
           
a(0,a)         
b(1,a)         
c(7,a)(2,b)        
d(22,a)(22,a)(22,a)       
e(∞,a)(∞,a)(∞,a)(∞,a)(31,f)(6,g)    
f(∞,a)(∞,a)(30,c)(11,d)      
g(∞,a)(∞,a)(∞,a)(16,d)(16,d)     
h(∞,a)(∞,a)(∞,a)(∞,a)(35,f)(35,f)(35,f)(35,f)(24,j)(8,i)
i(∞,a)(∞,a)(∞,a)(∞,a)(∞,a)(∞,a)(∞,a)(∞,a)(13,j) 
j(∞,a)(∞,a)(∞,a)(∞,a)(∞,a)(∞,a)(∞,a)(5,k)  
k(∞,a)(∞,a)(∞,a)(∞,a)(28,f)(28,f)(28,f)   

- modré hrany, které tvoří minimální kostru zadaného grafu: {a,b},{b,c},{a,d},{g,e},{d,f},{d,g},{i,h},{j,i}, {k,j},{f,k}

Dijkstrův algoritmus - nalezení nejkratší vzdálenosti mezi vrcholem a a vrcholem h

 abcdefghijk
a 1722       
b1 2        
c72   30     
d22    1116    
e     316    
f  301131 1835  28
g   16618     
h     35  824 
i       8 13 
j       2413 5
k     28   5 
                     
a (0,a)                  
b (1,a)                  
c (7,a) (3,b)                
d (22,a) (22,a) (22,a)              
e (∞,a) (∞,a) (∞,a) (∞,a) (64,f) (44,g)        
f (∞,a) (∞,a) (33,c) (33,c)            
g (∞,a) (∞,a) (∞,a) (38,d) (38,d)          
h (∞,a) (∞,a) (∞,a) (∞,a) (68,f) (68,f) (68,f) (68,f) (68,f) (68,f)
i (∞,a) (∞,a) (∞,a) (∞,a) (∞,a) (∞,a) (∞,a) (∞,a) (79,j)  
j (∞,a) (∞,a) (∞,a) (∞,a) (∞,a) (∞,a) (∞,a) (66,k)    
k (∞,a) (∞,a) (∞,a) (∞,a) (61,f) (61,f) (61,f)      

- nejkratší cesta mezi danými vrcholy je (a,b,c,f,h)

Příklad

Najděte nejkratší cestu mezi vrcholy a a d pomocí Dijkstrova algoritmu. Graf nekreslete!

abcde
a222
b21
c212
d21
e21

Nejprve si pod sebe napíšeme všechny vrcholy počínaje výchozím vrcholem:

a
b
c
d
e

Potom do našeho zápisu doplníme vzdálenost jednotlivých vrcholů od vrcholu a a přes jaký vrchol jsme této vzdálenosti dosáhli. Pokud vzdálenost neznáme, zapíšeme ∞.

abcde
a222
b21
c212
d21
e21
 
a(0,a)
b(2,a)
c(2,a)
d(∞,a)
e(2,a)

Dále pokračujeme z vrcholu b, protože máme volnou hranu o velikosti 1 incidentní s tímto vrcholem. Opět zapisujeme vzdálenost až z vrcholu a, tzn. že přičítáme hodnotu u vrcholu b. Pokud je ovšem vzdálenost přes vrchol b větší než původní vzdálenost, necháme původní hodnotu.

abcde
a222
b21
c212
d21
e21
 
a(0,a)
b(2,a)(2,a)
c(2,a)(2,a)
d(∞,a)(∞,a)
e(2,a)(2,a)

Opět pokračujeme stejným způsobem z dalšího vrcholu incidentního s další nejmenší hranou, tentokrát e.

abcde
a222
b21
c212
d21
e21
 
a(0,a)
b(2,a)(2,a)
c(2,a)(2,a)(2,a)
d(∞,a)(∞,a)(3,e)
e(2,a)(2,a)(2,a)

Zbývá již pouze jedna hrana a vrchol c nebo d.

abcde
a222
b21
c212
d21
e21
 
a(0,a)
b(2,a)(2,a)
c(2,a)(2,a)(2,a)(2,a)
d(∞,a)(∞,a)(3,e)(3,e)
e(2,a)(2,a)(2,a)

Z našeho zápisu jasně vyplývá, že vzdálenost z vrcholu a do vrcholu d je 3 a to přes vrchol e.

Z ilustrace algoritmu je souvislost Jarníkova řešení problému minimální kostry a Dijkstrova řešení nalezení nejkratších cest z daného vrcholu do ostatních již zcela patrná. V každém kroku z vrcholů ještě do modrého stromu nezařazených vybíráme v Jarníkově případě ten, který je nejblíže modrému stromu a v Dijkstrově případě ten, který je nejblíže počátečnímu vrcholu.

Pro úplnost uvádíme formulaci Dijkstrova algoritmu nalezení nejkratší cesty z daného vrcholu do ostatních vrcholů tak, jak je zapsána v práci [4]

Určení vzdálenosti z daného vrcholu nezáporně hranově ohodnoceného grafu

Vstupní data: Nezáporně hranově ohodnocený orientovaný graf G a jeho vrchol u.

Úkol: Pro každý vrchol v grafu G určit dv, vzdálenost z u do v.

Pomocné proměnné:

  • M, množina vrcholů, pro které ještě není vzdálenost dv určena definitivně, pro každý vrchol v je udán vrchol Vv, který je předposledním vrcholem nejkratší cestyu do v a neprochází vrcholy množiny M,
  • Lvw, přímá vzdálenost z vrcholu v do vrcholu w.
  1. [Inicializace] Je-li v = w, pak Lvw:= 0;

    je-li (v,w) hrana G, pak Lvw := délka hrany (v,w);

    je-li v ≠ w a (v,w) není hrana G, pak Lvw := +∞;

    M := množina vrcholů G různých od u; du := 0; Vu := u;

    je-li v vrchol G různý od u, položíme dv := Luv a je-li dv < +∞,

    pak položíme Vv := u.

  2. [Test ukončení] Je-li množina M prázdná, výpočet končí.
  3. [Určení dv pro další vrchol] Z vrcholů množiny M vybereme vrchol v s minimální hodnotou dv (je-li jich více, pak libovolný z nich). Je-li dv = +∞, výpočet končí, jinak vyjmeme v z množiny M.
  4. [Aktualizace dw a Vw] Je-li v vrchol vybraný v bodě 3, pak pro každý vrchol w ležící v M provedeme v případě, že platí dv + Lvw < dw, příkazy Vw := v a dw := dv + Lvw.
  5. Skok do bodu 2.

Řešený příklad

1. Určete délku nejkratších cest mezi vrcholem a a ostatními vrcholy za pomoci Dijkstrova algoritmu.

ohodnocený graf

Krok 1

Začneme ve vrchole a, označíme ho modře a každému vrcholu přiradím informaci = nejkratší momentální vzdálenost od vrcholu a přes incidentní hranu s modrou kostrou (každému vrcholu, který je sousední s a, přiřadíme velikost hrany +a, vrcholu, který není incidentní, přiřadím nekonečno):

překreslený graf

Krok 2

Projdeme hodnoty u všech vrcholů a vybereme nejmenší (u stejných se řídíme lexikografickým pravidlem).

Hodnoty: 2a, 7a, 6a, ∞, ∞, ∞. Nejmenší je 2a u vrcholu b. Do kostry vložíme vrchol b, hranu ab obarvíme modře a propočítáme hodnoty u ostatních vrcholů (u sousedů vrcholu b: když je součet hodnoty hrany a vzdáleností vrcholu b od a menší než aktuální hodnota vrcholu, tak přepíšeme aktuální hodnotu na novou +b, u vrcholu nesousedních s b, hodnota zůstává stejná):

  • vrchol d – je s b spojen hranou velikosti 3, 3 + 2(vzdálenost a-b) = 5, což je menší než hodnota 6a, proto přepíšeme na 5b,
  • vrchol c – je spojen s b hranou velikosti 8, 8+2 = 10, což je větší než aktuální hodnota 7a, proto necháme 7a

1. krok

Krok 3

Hodnoty: 5b, 7a, ∞, ∞, ∞. Nejmenší je 5b u vrcholu d. Vrchol d přidáme do kostry a hranu bd obarvíme modře. Propočítáme hodnoty u ostatních vrcholů sousedních s d:

  • vrchol c - je s d spojen hranou velikosti 2, 2 + 5 = 7, což je stejné jako aktuální hodnota 7a, můžeme přepsat na 7d nebo nechat 7a (osobní volna)
  • vrchol e - je s d spojen hranou velikosti 17, 17 + 5 = 22, což je menší než aktuální hodnota ∞, přepíšeme na 22d

2. krok

Krok 4

Hodnoty: 7a, 22d, ∞, ∞. Nejmenší hodnota je 7a u vrcholu c. Vrchol c přidáme do kostry a hranu ac obarvíme modře. Propočítáme hodnoty u ostatních vrcholů sousedních s c. Žádné vrcholy, které nepatří do kostry a jsou sousední s vrcholem c neexistují. Všechny hodnoty u ostatních vrcholů zůstanou nezměněné.

3. krok

Krok 5

Hodnoty: 22d, ∞, ∞. Nejmenší je 22d u vrcholu e. Do kostry vložíme vrchol e, hranu de obarvíme modře a propočítáme hodnoty u sousedních vrcholů:

  • vrchol f - je s e spojen hranou velikosti 5, 5 + 22 = 27, což je menší než nekonečno, přepíšeme na 27e
  • vrchol g - je s e spojen hranou velikosti 7, 7 + 22 = 29, což je menší než ∞, přepíšeme na 29e

4. krok

Krok 6

Hodnoty: 27e, 29e. Nejmenší je 27e u vrcholu f. Do kostry vložíme vrchol f, hranu ef obarvíme modře a propočítáme hodnoty u sousedních vrcholů:

  • vrchol g - je s f spojen hranou velikosti 4, 4 + 27 = 31, což je větší než 29e, nechám aktuální hodnotu

5. krok

Krok 7

Hodnoty: 29e. Jediná a teda nejmenší. Vrchol g vložím do kostry a hranu eg obarvíme modře.

výsledek
cesta mezi vrcholyvelikostcesta
a-b2a,b
a-c7a,c
a-d5a,b,d
a-e22a,b,d,e
a-f27a,b,d,e,f
a-g29a,b,d,e,g

2. Najděte všechny nejkratší vzdálenosti a cesty mezi vrcholem a a ostatními vrcholy.

abcdefg
a276
b283
c782
d63217
e1757
f54
g74

Krok 1

Začneme ve vrchole a, označíme ho modře a každému vrcholu přiradím informaci = nejkratší momentální vzdálenost od vrcholu a přes incidentní hranu s modrou kostrou (každému vrcholu, který je sousední (má v matici číslo-velikost hrany) s a, přiřadíme velikost hrany +a, vrcholu, který není incidentní (nemá v matici číslo), přiřadím nekonečno):

abcdefg
a276
b283
c782
d63217
e1757
f54
g74
-
2a
7a
6a

Krok 2

Projdeme hodnoty u všech vrcholů a vybereme nejmenší (u stejných se řídíme lexikografickým pravidlem).

Hodnoty: 2a, 7a, 6a, ∞, ∞, ∞. Nejmenší je 2a u vrcholu b. Do kostry vložíme vrchol b a propočítáme hodnoty u ostatních vrcholů (u sousedů vrcholu b: když je součet hodnoty hrany a vzdáleností vrcholu b od a menší než aktuální hodnota vrcholu, tak přepíšeme aktuální hodnotu na novou +b, u vrcholu nesousedních s b, hodnota zůstává stejná):

  • vrchol d – je s b spojen hranou velikosti 3, 3 + 2(vzdálenost a-b) = 5, což je menší než hodnota 6a, proto přepíšeme na 5b,
  • vrchol c – je spojen s b hranou velikosti 8, 8+2 = 10, což je větší než aktuální hodnota 7a, proto necháme 7a
abcdefg
a276
b283
c782
d63217
e1757
f54
g74
--
2a-
7a7a
6a5b

Krok 3

Hodnoty: 7a, 5b, ∞, ∞, ∞. Nejmenší je 5b u vrcholu d. Vrchol d přidáme do kostry. Propočítáme hodnoty u ostatních vrcholů sousedních s d:

  • vrchol c - je s d spojen hranou velikosti 2, 2 + 5 = 7, což je stejná jako aktuální hodnota 7a, můžeme přepsat na 7d nebo nechat 7a (osobní volba)
  • vrchol e - je s d spojen hranou velikosti 17, 17 + 5 = 22, což je menší než aktuální hodnota ∞, přepíšeme na 22d
abcdefg
a276
b283
c782
d63217
e1757
f54
g74
---
2a--
7a7a7a
6a5b-
22d

Krok 4

Hodnoty: 7a, 22d, ∞, ∞. Nejmenší hodnota je 7a u vrcholu c. Vrchol c přidáme do kostry. Propočítáme hodnoty u ostatních vrcholů sousedních s c. Žádné vrcholy, které nepatří do kostry a jsou sousední s vrcholem c neexistují. Všechny hodnoty u ostatních vrcholů zůstanou nezměněné.

abcdefg
a276
b283
c782
d63217
e1757
f54
g74
----
2a---
7a7a7a-
6a5b--
22d22d

Krok 5

Hodnoty: 22d, ∞, ∞. Nejmenší je 22d u vrcholu e. Do kostry vložíme vrchol e a propočítáme hodnoty u sousedních vrcholů:

  • vrchol f - je s e spojen hranou velikosti 5, 5 + 22 = 27, což je menší než nekonečno, přepíšeme na 27e
  • vrchol g - je s e spojen hranou velikosti 7, 7 + 22 = 29, což je menší než ∞, přepíšeme na 29e
abcdefg
a276
b283
c782
d63217
e1757
f54
g74
-----
2a----
7a7a7a--
6a5b---
22d22d-
27e
29e

Krok 6

Hodnoty: 27e, 29e. Nejmenší je 27e u vrcholu f. Do kostry vložíme vrchol f a propočítáme hodnoty u sousedních vrcholů:

  • vrchol g - je s f spojen hranou velikosti 4, 4 + 27 = 31, což je větší než 29e, nechám aktuální hodnotu
abcdefg
a276
b283
c782
d63217
e1757
f54
g74
------
2a-----
7a7a7a---
6a5b----
22d22d--
27e-
29e29e

Krok 7

Hodnoty: 29e. Jediná a teda nejmenší. Vrchol g vložím do kostry.

abcdefg
a276
b283
c782
d63217
e1757
f54
g74
------
2a-----
7a7a7a---
6a5b----
22d22d--
27e-
29e29e

Krok 8

Všechny vrcholy jsou v kostře a každý vrchol nese informaci o velikosti nejkratší cesty z vrcholu a, a také do kterého vrcholu se má posunout, aby se dostal k a:

cesta mezi vrcholyvelikostcesta
a-b2a,b
a-c7a,c
a-d5a,b,d
a-e22a,b,d,e
a-f27a,b,d,e,f
a-g29a,b,d,e,g

Úlohy k řešení

1. Kolik nejvíce vrcholů může mít graf, který má největší možnou vzdálenost mezi dvěma vrcholy rovnou 2?

Výsledek

počet vrcholů není omezen

příklad

2. Jaké jsou vzdálenosti všech vrcholů od vrcholu a?

Výsledek

dG(a,a) = 0, dG(a,b) = 2, dG(a,c) = 8, dG(a,d) = 7, dG(a,e) = 3, dG(a,f) = 5, dG(a,g) = 6, dG(a,h) = 3

3. V jakém pořadí budou zpracovány vrcholy při běhu Dijkstrova algoritmu s výchozím vrcholem a?

Výsledek

a, b, h, e, f, g, d, c nebo a, b, e, h, f, g, d, c

4. Dijkstrovým algoritmem určete vzdálenost a minimální cestu všech vrcholů od vrcholu a.

Graf

Výsledek

Vzdálenosti od vrcholu a
VrcholVzdálenost od aMin. cesta od a
b-1ab
c-2abc
d-2ad
e-3ade
f-6abcf
g-8adeg

5. Určete vzdálenost vrcholu j od vrcholu a.

Graf

Výsledek

Graf vzdáleností

Vzdálenost cesty aj je 66 a cesta je a,b,c,f,k,j.

Zdroje textů

  1. DIMA - diskrétní matematika, http://oliva.uhk.cz
  2. Dijkstrův algoritmus, http://www.algoritmy.net/article/5108/Dijkstruv-algoritmus
  3. Kovář, Petr. DISKRÉTNÍ MATEMATIKA a ÚVOD DO TEORIE GRAFŮ ( příklady k procvičení ), 2012
  4. Kučera, L.. Kombinatorické algoritmy. Praha: SNTL, 1989