Dijkstra algoritmusa: legrövidebb utak A probléma: Adott egy irányított vagy irányítatlan, súlyozott (élű) gráf, hogyan lehet megkeresni egy adott pontból egy másik pontba vezető legrövidebb (legkisebb súlyösszegű) utat?
E. Dijkstra (1972 Turing díj győztese) Dijkstra algoritmusa “Computer science is no more about computers than astronomy is about telescopes.” Született: 1930 május 11. Rotterdam, Hollandia Meghalt: 2002. augusztus 6. Nuenen, Hollandia E. Dijkstra (1972 Turing díj győztese)
Legrövidebb utak Dijkstra algoritmus(1959): pl. www.mapquest.com Gyorsabb algoritmusok 1990-től
Dijkstra algoritmusa Alapgondolat: mindig a kiindulási csúcshoz „legközelebbi” csúcsot választjuk A csúcsokat címkézzük, ez az odavezető utak élsúlyainak összege, ezt javítjuk, ha lehet. Az algoritmus működésének megértését ebben a példában a csúcsok színezésével segítjük, de ez NEM része az algoritmusnak. Zöld: A csúcsnak még ideiglenes a címkéje Sárga: legkisebb ideiglenes címkéjű csúcs, akkor lesz piros, ha a szomszédjait frissítettük - update lépés (ez nem feltétel, csak várakozás!) Piros: A csúcs címkéje már nem változik Obtain a network, and use the same network to illustrate the shortest path problem for communication networks, the max flow problem, the minimum cost flow problem, and the multicommodity flow problem. This will be a very efficient way of introducing the four problems. (Perhaps under 10 minutes of class time.)
A kulcslépés a legrövidebb utakat megkereső Dijkstra algoritmusban A d( ) jelöli a csúcs ideiglenes címkéjét, távolságát a kezdőcsúcstól. d(i) Az i. csúcs címkéje= az adott út hossza (úton lévő élek élsúlyainak összege) a kezdőcsúcstól. Ezt módosítjuk, ha találunk rövidebb utat C ij az i és j csúcsokat összekötő (i, j) él súlya (költsége) pred(j)= a j őse az adott úton Procedure Update(i) for MINDEN (i,j) élre do if d(j) > d(i) + cij then d(j) : = d(i) + cij és pred(j) : = i; Update(i) Ezt a Dijkstra algoritmusban használjuk.
PÉLDA: Update(7) Tegyük fel, hogy d(7) = 6 az 1-8-2-7 úton 9 5 3 1 8 2 11 8 8 1 8 2 7 3 4 6 7 Nincsen változás Legyen a 7 szomszédos a 9, 5, 3 csúcsokkal, melyeknek ideiglenes címkéi (1-től való távolságai) rendre 11, 9 és 8. Update(7) eredményképpen a 11-et javítjuk 8-ra, a 9-et 7-re, a 8 változatlan marad
Update-Megjegyzések a.) A címkék csak csökkenhetnek 1 8 2 7 9 5 3 4 6 9 5 11 Nincsen változás b.) Más lehetőség: szokás a pred(j) tömb helyett minden csúcsra egy LIST-át karbantartani, amely az adott csúcshoz vezető út csúcsait tartalmazza. A címke átállításakor a lista utolsó elemét töröljük, majd az új ős azonosítóját hozzáfűzzük.
Dijkstra elvi algoritmus begin S : = {1} ; T = N – {1}; d(1) : = 0 pred(1) : = 0; d(j) = for j = 2 to n; update(1); while S N do begin (csúcs kiválasztása) i ÎT az a csúcs, ami legközelebb van j-hez: d(i) = min {d(j) : j Î T}; S : = S È {i}; T: = T – {i}; Update(i) end; Procedure Update(i) for MINDEN (i,j) élre do if d(j) > d(i) + cij then d(j) : = d(i) + cij és pred(j) : = i; /* d(j) a j. csúcs távolsága az elsőtől az eddigi utak alapján –ezt javítjuk, ha tudjuk*/
Példa Dijkstra Algoritmusára (MIT) 4 2 4 2 2 1 2 3 1 1 6 4 2 3 3 5 Inicializálás: végtelenre állítjuk a címkéket, kivéve az induló csúcsot, ez 0 címkét kap. Az ideiglenes címkék közül válasszuk a legkisebbet: ez az 1 csúcs most (sárgával jelölve, szomszédjainak átcímkézése után lesz piros)
Update lépés (szükség esetén átcímkézés) 2 4 2 4 2 2 1 2 3 1 6 4 2 3 3 5 4 A kiválasztott csúcs szomszédjainak címkéit szükség szerint javítjuk, ti., ha az odavezető úton lévő súlyok összege az eddigi címkénél kisebb: a 2 és 3 csúcs címkéje emiatt 2 és 4 lesz.
Az ideiglenes címkék közül válasszuk ki a legkisebbet (sárga) 2 4 2 4 2 2 1 2 3 1 6 4 2 3 3 5 4 A kiválasztott csúcs mindig az előzőleg kiválasztott csúcs legkisebb címkéjű szomszédja. Ez van „legközelebb” az előzőleg kiválasztott csúcshoz.
Update lépés (átcímkézés) 6 2 4 2 4 2 2 1 2 3 1 6 4 2 3 3 5 4 4 3 A kiválasztott csúcs szomszédjaira: a 3 csúcs címkéje megváltozik d(3)=4-ről d(3)=3-ra, tehát a 3-ba a 2 csúcson keresztül kell menni, a végtelen címkéjűek megkapják a most kiszámolt út hosszát címkének ( az átcímkézés után a sárga csúcsból piros lesz).
Az ideiglenes címkék közül válasszuk ki a legkisebbet (sárga) 2 6 4 2 4 2 2 1 2 3 1 6 4 2 3 3 5 3 4
Update (átcímkézés) 2 6 4 2 4 2 2 1 2 3 1 6 4 2 3 3 5 3 4 d(5) nem változott ( az átcímkézés után a sárga csúcsból piros lesz)
Az ideiglenes címkék közül válasszuk ki a legkisebbet (sárga) 2 6 4 2 4 2 2 1 2 3 1 6 4 2 3 3 5 3 4
Update (átcímkézés) 2 6 4 2 4 2 2 6 1 2 3 1 6 4 2 3 3 5 3 4 d(4) nem változott ( az átcímkézés után a sárga csúcsból piros lesz)
Az ideiglenes címkék közül válasszuk ki a legkisebbet (sárga) 2 6 4 2 4 2 2 1 2 3 6 1 6 4 2 3 3 5 3 4
Update (átcímkézés) 2 6 4 2 4 2 2 1 2 3 6 1 6 4 2 3 3 5 3 4 d(6) nem változott ( az átcímkézés után a sárga csúcsból piros lesz)
Az ideiglenes címkék közül válasszuk ki a legkisebbet (sárga) 2 6 4 2 4 2 2 1 2 3 6 1 6 4 2 3 3 5 3 4 Nincs változás, a kiválasztott sárgával jelölt csúcsból piros lesz
Az algoritmus vége 2 6 4 2 4 2 2 1 2 3 6 1 6 4 2 3 3 5 3 4 -Most már mindegyik csúcs állandó címkével rendelkezik. -A kiválasztott élek és végpontjaik FÁT adnak. - Fában két pont között vezető út egyértelmű, így az 1 csúcsból a többibe vezető legrövidebb út is.
A kulcslépés a legrövidebb utakat megkereső Dijkstra algoritmusban A d( ) jelöli a csúcs ideiglenes címkéjét, távolságát a kezdőcsúcstól. d(i) Az i. csúcs címkéje= az adott út hossza (úton lévő élek élsúlyainak összege) a kezdőcsúcstól. Ezt módosítjuk, ha találunk rövidebb utat C ij az i és j csúcsokat összekötő (i, j) él súlya (költsége) pred(j)= a j őse az adott úton Procedure Update(i) for MINDEN (i,j) élre do if d(j) > d(i) + cij then d(j) : = d(i) + cij és pred(j) : = i; Update(i) Ezt a Dijkstra algoritmusban használjuk.
Dijkstra elvi algoritmus begin S : = {1} ; T = N – {1}; d(1) : = 0 pred(1) : = 0; d(j) = for j = 2 to n; update(1); while S N do begin (csúcs kiválasztása) i ÎT az a csúcs, ami legközelebb van j-hez: d(i) = min {d(j) : j Î T}; S : = S È {i}; T: = T – {i}; Update(i) end; Procedure Update(i) for MINDEN (i,j) élre do if d(j) > d(i) + cij then d(j) : = d(i) + cij és pred(j) : = i; /* d(j) a j. csúcs távolsága az elsőtől az eddigi utak alapján –ezt javítjuk, ha tudjuk*/
Források: MIT : http://web.mit.edu/jorlin/www/15.082/Animations Klostermayer lapja (fényképek, idézet) Klostermayer Erdős száma 2:) http://www.unf.edu/~wkloster/