Gráfok 2. Legrövidebb utak, feszítőfák előadás http://nik.uni-obuda.hu/sztf2 Szénási Sándor Óbudai Egyetem,Neumann János Informatikai Kar
Legrövidebb utak keresése Minimális feszítőfa keresése Gráfok 2
Adott csúcsból induló legrövidebb utak A szélességi keresés megadta a súlyozatlan gráfokban a legrövidebb utakat (itt az út hossza alatt az azt alkotó élek számát értettük) Ennek megfelelően a gráf legyen súlyozott A gráf legyen összefüggő Súlyozott gráfok esetében az egyes élekhez súlyokat rendelünk, és azt az utat keressük, ahol az azt alkotó élek súlyainak az összege minimális Megfontolandó Negatív súlyú éleket is tartalmazó gráfok esete Negatív összsúlyú köröket is tartalmazó gráfok esete Gyakorlati alkalmazások 5 2 4 5 4 2 2 8 4 6 7 2
Fokozatos közelítés elve A fokozatos közelítés technikája során Folyamatosan tároljuk az egyes csúcsokhoz a kiindulópontból eddig talált legrövidebb út hosszát (d), ami egy felső becslés a végeredményre Minden csúcsnál eltároljuk azt, hogy ezen az úton melyik csúcsból értük el az adott csúcsot (π) A közelítés elve Kiinduló állapot A kezdőcsúcs esetében d[start] = 0 és π[start] = A többi csúcshoz még nem találtunk utat, ezért ezeknél a távolság értékeket végtelenre állítjuk, a megelőző csúcsokat pedig -ra Közelítés Ha találunk olyan (u, v) élt, amelyre igaz, hogy d[u] + u.súly(v) < d[v] Akkor ez azt jelenti, hogy a v csúcshoz találtunk egy eddig találtnál rövidebb utat, ennek megfelelően módosítjuk a d és π értékeket: d[v] d[u] + u.súly(v) (az új legrövidebbnek gondolt út hossza) π[v] u (ezen az úton a megelőző csúcs) Megfelelő sorrendben hajtva végre a közelítést bizonyítható, hogy meg fogjuk találni a legrövidebb utat minden csúcshoz 4
Dijkstra algoritmusa függvény Dijkstra(G, start) ciklus x G.Csúcsok d[x] ; π[x] S x d[start] 0 ciklus amíg S u S.MinKivesz(d) ciklus x u.szomszédok ha d[u] + u.súly(x) < d[x] akkor d[x] d[u] + u.súly(x) π[x] u elágazás vége vissza (π, d) függvény vége Ahol S egy prioritásos sor. Az S.MinKivesz(d) művelet pedig azt az x S sorbeli elemet adja vissza, ahol a d[x] érték a legkisebb Előfeltétel: a gráf irányított és nem tartalmazhat negatív súlyú éleket! 5
6 Az algoritmus eredménye Az algoritmus eredménye d[x] mutatja minden x csúcs esetén az oda vezető legrövidebb út hosszát (vagy végtelen, ha nincs ilyen) π[x] mutatja a fenti úton a megelőző csúcsot (kivéve a kiinduló és az el nem ért csúcsokat) Tényleges utak előállítása A cél csúcsból elindulva a π-ben található adatok alapján visszafelé lépkedve előállíthatjuk az egyes csúcsokba vezető utakat Addig megyünk, amíg a kezdőcsúcshoz nem érünk (ahol π értéke ) Pl. egy láncolt lista elejébe szúrva a fenti egyszerűen megoldható Legrövidebb utakat tartalmazó fa előállítása Az algoritmus a kezdőcsúcsból minden elérhető csúcsba előállítja a legrövidebb utat A π értékek alapján előállítható egy olyan fa, amely ezeket az utakat tartalmazza Hasonló a szélességi keresésnél is már megismert szélességi fához
További megoldható feladatok Egy csúcsból az összes többi csúcsba vezető legrövidebb utak megkeresése Nincsenek negatív élek: Dijkstra algoritmus Lehetnek negatív élek: Bellman-Ford algoritmus (nem tárgyaljuk) Egy csúcsba vezető legrövidebb utak problémája Az összes csúcsból a cél csúcsba vezető legrövidebb utakat keressük Élek irányításának megfordításával könnyen megoldható Két adott csúcs közötti legrövidebb út problémája A Dijkstra algoritmus a végén erre is választ ad Ennél sokkal jobb megoldásunk nincs Összes csúcspár közötti legrövidebb utak keresése A gráf minden u és v csúcsa között megkeressük a legrövidebb utat Lefuttathatjuk a Dijkstra algoritmust minden csúcsból kiindulva Léteznek erre specializált megoldások (pl. Floyd-Warshall algoritmus) Irányítatlan gráfok esete Ha nincs negatív él, akkor a Dijkstra használható kis módosítással Negatív él egyben negatív kört is jelent 7
Legrövidebb utak keresése Minimális feszítőfa keresése Gráfok 2.
9 Minimális feszítőfa előállítása Olyan feszítőfát keresünk, ahol az élek összsúlya minimális Ennek megfelelően a gráf legyen súlyozott A gráf legyen irányítatlan Legyen összefüggő Egy gráfnak több minimális feszítőfája is lehet, ezek közül elég az egyiket megtalálnunk Gyakorlati alkalmazások Áramkörök tervezése Ellátórendszerek tervezése 5 2 4 5 4 2 8 4 6 7 2
0 Feszítőfa növelésének elve Feszítőfa növelése során Egy alapállapotból kiindulva, egyesével adjuk hozzá az éleket a leendő feszítőfához Tehát az algoritmus minden állapotában a feszítőfa egy részét tartja nyilván (nevezzük ezt A-nak) A feszítőfa lépésenkénti növelésének elve Kiinduló állapot Az A kezdőértéke legyen egy olyan állapot, ami biztosan a leendő feszítőfa része lesz majd (pl. egy darab csúcs, vagy egy jól megválasztott él) Növelés Ezt követően olyan éleket keresünk, amelyeket hozzáadva az eddigi A állapothoz, továbbra is fennáll a fenti állítás (az A továbbra is a leendő feszítőfa egy része) Ezeket biztonságos éleknek nevezzük Egy ilyen élet hozzáadunk az A-hoz Addig ismételjük, amíg A nem feszítőfa Biztonságos él megállapítása
Biztonságos él keresése Vágásnak nevezzük a gráf csúcsainak a kettéosztását két csoportba pl. ábrán a zöld vonal bal és jobb oldalán lévő elemekre Azt mondjuk, hogy egy él keresztezi a vágást, ha a két végpontja a két különböző csoportba került pl. az ábrán a piros élek Egy él könnyű egy vágásban, ha a vágást keresztező élek közül neki van a legkisebb a súlya pl. az ábrán a vastagabb piros él Egy vágás kikerül egy A halmazt, ha az A egyik éle sem keresztezi a vágást Bizonyítható, hogy ha van egy A halmazunk, amely egy G gráf éleinek részhalmaza, továbbá G egy minimális feszítőfájának is része, akkor az G gráf A-t kikerülő vágásainak könnyű élei biztonságosak 5 2 4 5 4 2 8 4 6 7 2
Prim algoritmusa függvény Prim(G, start) ciklus x G.Csúcsok k[x] ; π[x] S x k[start] 0 ciklus amíg S u S.MinKivesz(k) ciklus x u.szomszédok ha x S u.súly(x) < k[x] akkor k[x] u.súly(x) π[x] u elágazás vége vissza π függvény vége Ahol S egy prioritásos sor. Az S.MinKivesz(k) művelet pedig azt az x S sorbeli elemet adja vissza, ahol a k[x] érték a legkisebb Visszatérési értéke a szülőket tartalmazó adatszerkezet 2
Kruskal algoritmusa függvény Kruskal(G) ciklus x G.Csúcsok Halmaz-létrehozás(x) ciklus (u,v) G.Élek S (u,v) ciklus amíg S (u,v) S.MinKivesz(súly) ha Tartalmazó-halmaz(u) Tartalmazó-halmaz(v) akkor A A {(u,v)} Halmaz-összevonás(Tartalmazó-halmaz(u), Tartalmazó-halmaz(v)) vissza A függvény vége Ahol S egy prioritásos sor, ami most az éleket tartalmazza. Az S.MinKivesz(súly) művelet pedig azt az e S sorbeli elemet adja vissza, ahol az él súlya a legkisebb Az eljárás visszatérési értéke a minimális feszítőfa éleinek halmaza
4 Kruskal segédműveletek Halmaz-létrehozás(x) Létrehoz egy új halmazt Ebben elhelyezi az x elemet (ami egy csúcs) Tartalmazó-halmaz(x) Az előzőleg létrehozott halmazok közül megkeresi azt, amelyikben az x szerepel Csak egy ilyen halmaz lehet, a visszatérési értéke ez a halmaz Halmaz-összevonás(A, B) Az előzőleg létrehozott halmazok közül összevon kettőt Tehát pl. az A legyen a két halmaz uniója, a B-t pedig megszünteti Megvalósítás Tényleges halmaz adatszerkezetekkel Objektumorientáltan (halmaz objektumok, illetve halmazok halmazai) A halmazok maximális száma és maximális elemszáma ismert (mind a kettő értéke V ), így tömbök egyszerűen használhatók Láncolt lista az összevonásnál praktikus Másik megoldás, ha halmazok helyett csak a csúcsokhoz rendelünk egy azonosítót, hogy melyik halmazban van (összevonás csak ennek a másolása)
5 Irodalomjegyzék Javasolt/felhasznált irodalom Aho, Hopcroft, Ulmann: Számítógép-algoritmusok tervezése és analízise, Műszaki Könyvkiadó, 982 Cormen, Leiserson, Rivest: Algoritmusok, Műszaki Könyvkiadó, 997 Szénási: Algoritmusok, adatszerkezetek II., Óbudai Egyetem, 204