Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
KiadtaKrisztina Kovács Megváltozta több, mint 9 éve
1
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 1 Programozás II. Gráfok Dijkstra algoritmus Kruskal algoritmus
2
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 2 Gráfok & Dijkstra algoritmus Gráf: csomópontok és a csomópontokat összekötő élek halmaza Jelenleg: irányítatlan, súlyozott gráf Cél: az 1. csúcsból meghatározni a legrövidebb utat az 5. csúcshoz Dijkstra algoritmus: meghatározza valamely kezdőcsúcsból az összes többi csúcsba vezető legkisebb súlyú utat Mohó algoritmus
3
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 3 Dijkstra algoritmus Tegyük fel, hogy a gráf tárolása és a lényeges műveletek már készen vannak Két tömböt használunk, mindegyik tömb ugyanannyi elemű, mint ahány csúcs van a gráfban Az int típusú ElozoCsucs tömbben tároljuk a kiinduló csúcsból az egyes csúcsokhoz vezető legrövidebb útnál a csúcsot megelőző csúcs sorszámát A double típusú OsszSuly tömbben tároljuk a kiinduló csúcsból az egyes csúcsokhoz vezető jelenleg ismert legrövidebb út összsúlyát Az csúcsokat két halmazra kell osztani: függőben lévő csúcsok és fix útvonalú csúcsok. Mi ezt úgy oldjuk meg, hogy az i. csúcs még függőben van, ha OsszSuly[i]<0 Jelenlegi kezdőcsúcs: #1 !
4
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 4 Inicializálás Kell: kiinduló csúcs (Honnan), innen számoljuk a legrövidebb utat az összes többi csúcshoz Minden I csúcs távolsága legyen az I és a Honnan csúcs távolságának negatív értéke: OsszSuly tömb –(a negatív távolság azt jelzi, hogy a csúcs még nincs kész) –(a Honnan-nal nem szomszédos csúcsoknál ez double.NegativeInfinity) Minden I csúcsra jelezzük, hogy a Honann I útvonalban az I csúcs előtti csúcs a Honnan (közvetlen él): ElozoCsucs tömb –(ez a Honnan csúccsal szomszédos csúcsokra tényleg jó útvonalat definiál, a többi csúcsnál nincs olyan él, szóval ez biztos változni fog) –A Honnan csúcs előtti csúcs legyen -1, ezzel jelezzük, hogy a Honnan a kiinduló-csúcs
5
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 5 Kiinduló állapot IDXElozoCsucsOsszSuly 10 21-10 31 -∞-∞ 41-5 51 -∞-∞
6
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 6 Algoritmus Ciklus, amíg van negatív súly (vagyis: amíg létezik nem-kész csúcs) 1.Minimum=az abszolút értékben legkisebb negatív súly sorszáma; 2.OsszSuly[minimum] = -OsszSuly[minimum]; 3.Minden nem-kész (vagyis negatív összsúlyú) csúcsra megnézzük, hogy a jelenlegi OsszSuly[i] súlynál abszolút értékben kisebb súlyt kapunk –e, ha nem az ElozoCsucs[i] eddigi előző csúcson, hanem a Minimum-csúcson keresztül közelítjük meg. Ha igen, akkor ezzel frissítjük az OsszSuly[i]-t, és ElozoCsucs[i]=Minimum; Ciklus vége
7
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 7 1. iteráció IDXElozoCsucsOsszSuly 10 21-10 31 -∞-∞ 41-5 51 -∞-∞ A LEGKISEBB! (Abszolút értékben) 5 -8 -14 -16 4
8
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 8 2. iteráció A LEGKISEBB! (Abszolút értékben) IDXElozoCsucsOsszSuly 10 24-8 34-14 415 54-16 8 -9 2
9
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 9 3. iteráció IDXElozoCsucsOsszSuly 10 248 32-9 415 54-16 A LEGKISEBB! (Abszolút értékben) -10 9 3
10
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 10 4. iteráció IDXElozoCsucsOsszSuly 10 248 329 415 53-10 A LEGKISEBB! (Abszolút értékben) 10
11
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 11 Végállapot IDXElozoCsucsOsszSuly 10 248 329 415 5310 Bármelyik csúcs elérhető a kezdőcsúcsból indulva Az útvonalak nem feltétlenül alkotnak fát vagy egyenest, ez egyedi
12
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 12 Fejlesztés Gráf osztály: int FPontok; double[,] FSulyok; string[] FCimkek; –public Graf(int n) –public void UjCimke(int n, string cimke) –public void UjEl(int n, int m, double suly) –public int GetPont(string cimke) –public double GetSuly(int n, int m) Dijkstra algoritmushoz szükséges eljárások: –private bool MinKer(double[] d, out int min) Visszaadja, hogy talált –e negatív súlyt, és ha talált, akkor ezek közül melyik az abszolút értékben a legkisebb –public List Utvonal(int honnan, int hova) Itt először legeneráljuk az ElozoCsucs + OsszSuly tömböket, aztán iterálunk, majd legeneráljuk a specifikus utat
13
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 13 Tesztelés (Ctrl+C, Ctrl+V) Graf g; g = new Graf(5); g.UjCimke(0, "#1"); g.UjCimke(1, "#2"); g.UjCimke(2, "#3"); g.UjCimke(3, "#4"); g.UjCimke(4, "#5"); g.UjEl(0, 1, 10); g.UjEl(0, 3, 5); g.UjEl(1, 3, 3); g.UjEl(1, 2, 1); g.UjEl(2, 3, 9); g.UjEl(3, 4, 11); g.UjEl(2, 4, 1); utvonal(g, g.GetPont("#1"), g.GetPont("#5"));
14
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 14 Tesztelés2 (Ctrl+C, Ctrl+V) g = new Graf(20); g.UjCimke(0, "Baja"); g.UjCimke(1, "Budapest"); g.UjCimke(2, "Debrecen"); g.UjCimke(3, "Eger"); g.UjCimke(4, "Esztergom"); g.UjCimke(5, "Győr"); g.UjCimke(6, "Gyula"); g.UjCimke(7, "Kaposvár"); g.UjCimke(8, "Kecskemét"); g.UjCimke(9, "Miskolc"); g.UjCimke(10, "Nyíregyháza"); g.UjCimke(11, "Pécs"); g.UjCimke(12, "Sopron"); g.UjCimke(13, "Szeged"); g.UjCimke(14, "Székesfehérvár"); g.UjCimke(15, "Szolnok"); g.UjCimke(16, "Szombathely"); g.UjCimke(17, "Tatabánya"); g.UjCimke(18, "Veszprém"); g.UjCimke(19, "Zalaegerszeg"); g.UjEl(0, 1, 192.5); g.UjEl(0, 6, 165.7); g.UjEl(0, 13, 93.1); g.UjEl(1, 2, 205.9); g.UjEl(1, 3, 240.3); g.UjEl(1, 8, 81.2); g.UjEl(1, 11, 197.8); g.UjEl(1, 18, 126.4); g.UjEl(2, 3, 35.6); g.UjEl(2, 6, 93.1); g.UjEl(3, 6, 104.3); g.UjEl(4, 7, 152.4); g.UjEl(4, 16, 133.8); g.UjEl(4, 17, 26.1); g.UjEl(5, 12, 33.4); g.UjEl(5, 16, 110.5); g.UjEl(6, 15, 72.3); g.UjEl(7, 11, 65.8); g.UjEl(7, 14, 99.9); g.UjEl(8, 9, 137.5); g.UjEl(8, 13, 91.8); g.UjEl(8, 15, 52.3); g.UjEl(9, 1, 210.4); g.UjEl(9, 6, 141.0); g.UjEl(9, 10, 62.7); g.UjEl(10, 2, 216.8); g.UjEl(10, 15, 44.6); g.UjEl(11, 0, 76.8); g.UjEl(11, 5, 258.2); g.UjEl(11, 14, 116.4); g.UjEl(11, 19, 145.0); g.UjEl(12, 14, 91.5); g.UjEl(12, 17, 60.7); g.UjEl(13, 1, 158.2); g.UjEl(13, 15, 56.3); g.UjEl(14, 1, 62.1); g.UjEl(14, 5, 97.4); g.UjEl(14, 17, 41.7); g.UjEl(15, 1, 109.8); g.UjEl(15, 3, 68.3); g.UjEl(16, 17, 127.5); g.UjEl(16, 19, 78.2); g.UjEl(17, 18, 69.1); g.UjEl(18, 11, 137.6); g.UjEl(18, 14, 46.3); g.UjEl(19, 1, 278.5); g.UjEl(19, 4, 207.2); g.UjEl(19, 6, 377.9); g.UjEl(19, 12, 92.7); utvonal(g, g.GetPont("Szombathely"), g.GetPont("Szeged"));
15
V 1.0 Tesztelés Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 15
16
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 16 Programozás II. Gráfok Dijkstra algoritmus Kruskal algoritmus
17
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 17 Kruskal algoritmus Fa: körmentes (aciklikus), összefüggő gráf Feszítőfa: a gráf összes csúcsát tartalmazó fa, amelynek élei a gráf éleinek részhalmazát alkotják, n csúcs esetén n-1 élből áll Minimális feszítőfa: a feszítőfák közül a legkisebb összsúlyú
18
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 18 "Nem alakul ki kör" ? Útvonalkereséssel (lassabb, talán könnyebben érthető) : Egy listába berakjuk az X csúcsból a feszítőfa meglévő élein keresztül elérhető összes csúcsot (tetszőleges bejárással: szélességi/mélységi). Ha a listában benne van az Y, akkor az X csúcsból a feszítőfa élein keresztül már elérhető az Y, vagyis X és Y egy komponensben van nem adható hozzá a feszítőfához az XY él, mert az kört hozna létre Komponensek használatával (ezt fogjuk implementálni) : Minden csúcshoz komponens-azonosítót rendelünk. Az él nem hoz létre kört, ha külön komponensben lévő csúcsokat köt össze: X és Y csúcs összeköthető éllel, ha a komponens-azonosítójuk különböző. Ezután minden csúcshoz azonos komponens-azonosítót kell rendelni, ami az X vagy az Y csúcs komponensében volt.
19
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 19 Kruskal algoritmus – példa
20
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 20 Kruskal algoritmus – példa
21
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 21 Kruskal algoritmus – példa
22
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 22 Kruskal algoritmus – példa
23
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 23 Kruskal algoritmus – példa
24
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 24 Kruskal algoritmus – példa
25
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 25 Kruskal algoritmus – példa
26
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 26 Kruskal algoritmus – példa
27
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 27 Kruskal algoritmus – megoldási elv 1.Definiáljuk a komponensek tömböt, ahol komponensek[i] az i. csúcs komponens-azonosítóját jelzi. Kezdetben minden tömbelem egyedi [0..X] nincs él a feszítőfában 2.double FSulyok[,] List Elek (GrafEl = {kezdőpont, végpont, súly}) 3.GrafEl rendezése súly szerint növekvő sorrendbe 4.Ciklus, amíg nincs kész a feszítőfa és nem fogynak el az élek a)Akt = sorrendben a következő él, ahol a kezdőpont és a végpont különböző komponensben van b)Ha van ilyen él, akkor az él hozzáadása a feszítőfához c)Ha van ilyen él, akkor az él kezdőpontjának és végpontjának a komponenseit egyesíteni kell 5. public List Kruskal()
28
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 28 Tesztelés (Ctrl+C, Ctrl+V) g = new Graf(8); g.UjCimke(0, "#1"); g.UjCimke(1, "#2"); g.UjCimke(2, "#3"); g.UjCimke(3, "#4"); g.UjCimke(4, "#5"); g.UjCimke(5, "#6"); g.UjCimke(6, "#7"); g.UjCimke(7, "#8"); g.UjEl(g.GetPont("#1"), g.GetPont("#2"), 1); g.UjEl(g.GetPont("#1"), g.GetPont("#6"), 3); g.UjEl(g.GetPont("#2"), g.GetPont("#6"), 4); g.UjEl(g.GetPont("#2"), g.GetPont("#3"), 2); g.UjEl(g.GetPont("#2"), g.GetPont("#7"), 5); g.UjEl(g.GetPont("#6"), g.GetPont("#7"), 8); g.UjEl(g.GetPont("#3"), g.GetPont("#7"), 6); g.UjEl(g.GetPont("#3"), g.GetPont("#4"), 4); g.UjEl(g.GetPont("#4"), g.GetPont("#7"), 7); g.UjEl(g.GetPont("#7"), g.GetPont("#8"), 1); g.UjEl(g.GetPont("#4"), g.GetPont("#8"), 6); g.UjEl(g.GetPont("#4"), g.GetPont("#5"), 7); g.UjEl(g.GetPont("#5"), g.GetPont("#8"), 8); kruskal(g);
29
V 1.0 Tesztelés Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 29
32
V 1.0 Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu 32 Képek forrásai http://people.ksp.sk/~kuko/bak/ (megjegyzés: a fenti oldal nagyon jó, de kicsit más a BST, mint az előadáson ismertetett: törlés-C esetnél (amikor mindkét gyermekeleme létezik a törlendő elemnek) nem a bal oldali részfa legjobboldalibb elemét, hanem a jobb oldali részfa legbaloldalibb elemét használja) http://en.wikipedia.org/wiki/Linked_List http://en.wikipedia.org/wiki/Dijkstra's_algorithm http://en.wikipedia.org/wiki/Kruskal's_algorithm http://people.inf.elte.hu/fekete/docs_2/grafalg/grafalg.htm http://www-b2.is.tokushima-u.ac.jp/~ikeda/suuri/kruskal/Kruskal.shtml http://students.ceid.upatras.gr/~papagel/project/pseukrus.htm http://www.cs.usask.ca/classes/371/projects/99group8/tutorial/advanced/prim/prim_kruskal.ht ml
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.