Föreläsning I07 FÖRELÄSNING DATALOGI I Grafer Beatrice Åkerblom beatrice@dsv.su.se Institutionen för Data- och Systemvetenskap SU/KTH
Föreläsning I07 Läsanvisningar Michael Main Data Structures & Other Objects Using Java (Upplaga: Second Edition), Addison Wesley, 003, ISBN : 0-0-7093- Grafer kapitel
Föreläsning I07 3 Föreläsningens innehåll Definition av grafbegreppet Användningsområden grafer Implementation av grafer för Genomgång av grafer (traversering) Algoritmer Minimala träd, spanning trees Kortaste vägen Prims algoritm Dijkstras algoritm Programmeringsprojekt
Föreläsning I07 Begrepp som kommer att tas upp graf oriktad graf nod riktad graf båge viktad graf väg djupet först -sökning subgraf bredden först -sökning
Föreläsning I07 5 Graf en definition En graf är en ickelinjär datastruktur bestående av noder och bågar mellan de ingående noderna. Grafens noder kan vara till varandra hursomhelst. I en graf finns ingen hierarkisk struktur. Vi kan se en graf som en mängd noder N : {A, B, C, D, E} och en mängd nodpar B : {(A, B), (A, C), (B, D), (C, D), (C, E)}
Föreläsning I07 6 Exempel på en graf N : {A, B, C, D, E} B : {(A, B), (A, C), (B, D), (C, D), (C, E)} D A E B C
Föreläsning I07 7 Fler grafexempel N : {A, B, C, D, E} B : {(A, B), (A, C), (A, D), (A, E), (B, C), (B, D), (B, E), (C, D), (C, E), (D, E)} N : { } B : { } D A E B C Komplett graf Tomma grafen
Föreläsning I07 8 Fler grafexempel N : {A, B, C, D, E} B : {(A, B), (A, C), (B, D), (C, D), (C, E)} N : {A, B, C, D, E} B : {(A, B), (A, C), (B, D), (C, D), (C, E)} A D E A D E B B C Två noder är angränsande om det finns en båge mellan dem C En väg är en sekvens av noder där varje par är en båge
Föreläsning I07 9 Oriktade grafer N : {A, B, C, D, E} B : {(B, A), (C, A), (D, A), (E, A), (C, B), (D, B), (E, B), (D, C), (E, C), (E, D)} N : {A, B, C, D, E} B : {(A, B), (A, C), (A, D), (A, E), (B, C), (B, D), (B, E), (C, D), (C, E), (D, E)} A D E A D E B B C Exakt samma resultat. Paren är oordnade. C
Föreläsning I07 0 Riktade grafer N : {A, B, C, D, E, F, G} B : {(A, B), (A, E), (A, F ), (B, C), (C, D), (D, B), (D, A), (D, G), (G, G)} A B E F C D G Varje båge har en utgångspunkt och ett mål Ordningen har betydelse.
Föreläsning I07 Viktade grafer N : {A, B, C, D, E, F, G} B : {(A, B), (A, E), (A, F ), (B, C), (C, D), (D, B), (D, A), (D, G), (G, G)} A B 3 C 7 D E G F 5 Varje båge har ett värde (ett icke-negativt tal). En viktad graf kan vara riktad eller oriktad
Föreläsning I07 Vad kan vi använda grafer till? Beskriva tunnelbanenätet Grön linje Röd linje Navigation på en webbsida Beskriva ett datornätverk Automater Beskriva förhållandet mellan objekt i ett objektorienterat program
Föreläsning I07 3 Vad behöver vi kunna göra med en graf? Lägga till och at bort noder Lägga till och ta bort bågar Ta reda på vilken information som är knuten till en viss nod Ta reda på om det finns någon båge mellan två noder och i så fall ta reda på vilken information den innehåller. Markera att vi besökt en viss nod i en genomgång och sedan undersöka om en viss nod är besökt eller ej Markera att vi passerat en viss båge i en genomgång och sedan undersöka om en viss båge har passerats eller ej
Föreläsning I07 Hur kan vi implementera en graf? Matris över angränsande noder (adjacency matrix) Tvådimensionell array med indikatorer för de olika bågarna Lista över bågarna Varje nod har en lista över angränsande noder Mängd med bågar Array med mängder av angränsande noder
Föreläsning I07 5 Matris över angränsande noder B A int[][] matris ={ { 0 0 0 0} { 0 { 0 0 0 0 0 0 0} 0 0 0 0} { { 0 { 0 { 0 0 0 0 0 0 0 0 } 0 0 0 0 0} 0 0 0 0 0} 0 0 0 0 }} C D E G F Från A B C D E F G Till A B C D E F G falsetrue false false falsetrue true true false false false false false false false falsetrue false false false true true false false false falsetrue false false false false false false false false false false false false false false false false false false false falsetrue
Föreläsning I07 6 Lista över bågarna noderna Nod[] noderna = new Nod[7]; 0 [0] [] [] [3] [] [5] [6] 3 0 6 3 6 5 5 6
Föreläsning I07 7 Lista över bågarna, forts. class Nod {... private Bage baglista;... } class Bage {... private Nod nod; private Bage next;... }
Föreläsning I07 8 Mängd med bågarna noderna Nod[] noderna = new Nod[7]; 0 [0] [] [] [3] [] [5] [6] 5 3 0 5 6 6 6 3
Föreläsning I07 9 Mängd med bågarna, forts. class Nod {... private BagMangd bagar;... } class BagMangd {... private int antal; private int[] nodnummer;... }
Föreläsning I07 0 Vilken slags representation skall vi välja? Matris över angränsande noder (adjacency matrix) Lätt att implementera Tar stor plats Onödigt om det är en graf med få bågar Lägga till och ta bort bagar/noder Undersöka om en viss båge finns Vilka operationer görs ofta? Det finns ingen grafimplementation som är den bästa i alla sammanhang
Föreläsning I07 Genomgång av en graf traversering Genomgång av en graf tills dess att man besökt alla de noder man kan nå. Beroende av var man börjar sin genomgång. djupet först -genomgång Använder en stack för att hålla reda på vilka noder man redan besökt Kan även implementeras med hjälp av rekursion bredden-först -genomgång Använder en kö för att hålla reda på vilka noder man redan besökt. I båda fallen ser man till att markera redan besökta noder för att undvika loopar i genomgången
Föreläsning I07 Djupet först -genomgång Vid en genomgång med djupet först strategin går man först så långt som möjligt på en viss väg (till vi stöter på en återvändsgränd eller en nod vi redan besökt. sedan backar vi tillbaka till den senast besökta noden med angränsande noder som ännu inte markerats som besökta
Föreläsning I07 3 Djupet först rekursiv noderna Nod[] noderna = new Nod[7]; 0 [0] [] [] [3] [] [5] [6] 3 0 6 3 djupf(graf g, Nod n, boolean[] markerad){ markera n; behandla n; förvarje granne till n{ djupf(g, granne, markerad) } } 6 5 5 6
Föreläsning I07 Djupet först iterativ djupf(nod n) { // går igenom en graf med början i noden n Stack s = createstack(); s.push(n); // pusha n på stacken och markera den som besökt n.markera(); while(!s.isempty()) { if(n.allagrannarbesokta()){ s.pop(); // backar } else { välj obesökt nod m, granne till n s.push(m); m.markera(); } } }
Föreläsning I07 5 Djupet först, forts. noderna Nod[] noderna = new Nod[7]; 0 [0] [] [] [3] [] [5] [6] 3 0 6 3 djupf(graf g, Nod n, boolean[] markerad){ markera n; behandla n; förvarje granne till n{ djupf(g, granne, markerad) } } 6 5 5 6
Föreläsning I07 6 Bredden först -genomgång Vid en genomgång med bredden först -strategin besöker vi först alla de noder som gränsar till utgångspunkten sedan fortsätter man till den första av grannarna besöker först alla dess grannar sedan fortsätter man till den första av dess grannar
Föreläsning I07 7 Bredden först -genomgång noderna Nod[] noderna = new Nod[7]; 0 [0] [] [] [3] [] [5] [6] 3 0 6 3 6 5 5 6
Föreläsning I07 8 Djupet först iterativ breddf(nod n) { // går igenom en graf med början i noden n Queue q = createqueue(); q.enqueue(n); // lägg till n i kön och markera den som besökt n.markera(); while(!q.isempty()) { Nod m = q.dequeue(); for(varje obesökt o granne till m){ o.markera(); q.enqueue(o); } } }
Föreläsning I07 9 Bredden först -genomgång igen noderna Nod[] noderna = new Nod[7]; 0 [0] [] [] [3] [] [5] [6] 3 0 6 3 6 5 5 6
Föreläsning I07 30 Djupet först i f a e 6 9 8 b 3 7 g c 5 d h Besökt nod a b c d g e back f back Stack botten topp a ab abc abcd abcdg abcdge abcdg abcdgf abcdg......
Föreläsning I07 3 Djupet först, forts. i a 6 9 b 7 c Besökt nod Stack botten topp...... back abcd f e 8 3 g 5 d h h back back back back i back abcdh abcd abc ab a ai (tom)
Föreläsning I07 3 Bredden först i f a e 6 9 8 b 3 7 g c 5 d h Besökt nod a b f i c e Kö uttag insättn. a (tom) b bf bfi fi fic fice ice......
Föreläsning I07 33 Bredden först, forts i f a e 6 9 8 b 3 7 g c 5 d h Besökt nod Kö uttag insättn....... g iceg ceg eg d egd gd d (tom) h h (tom)
Föreläsning I07 3 Kostnad Ofta vill vi veta mer än bara att det finns en väg Kostnad förknippad med bågarna hitta billigaste vägen A B 3 C 7 D E G F 5
Föreläsning I07 35 Spanning trees Väg genom alla noderna i en hel graf Alla noder förbundna med vissa, så få som möjligt, av bågarna Kortaste vägen genom en hel graf minimalt spanning tree, minimalt antal bågar och minimal vikt b 3.0 e b e 5.0 8.0 5.0 8.0 a 8.0 c 0.0 f a 8.0 c 0.0 f 7.0 8.0.0 8.0.0 d.0 g d g Graf Spanning Tree (inte minimalt)
Föreläsning I07 36 Hitta minimalt spanning tree Prims algoritm Använder sig av två olika samlingar, en för sorteringen och en för slutresultatet Går igenom en graf och stoppar in alla bågar i en prioritetskö och plockar ut dem igen
Föreläsning I07 37 Prims algoritm, forts. Börja med ett tomt träd T och en tom prioritetskö P K Lägg in noden (n, m, v) i P K tills vi i P Khar så många bågar som vi har från utgångsnoden i grafen Loopa och ta ut ur P K den båge som har lägst vikt (n, m, v), om m inte redan finns i T, lägg till både noden m och bågen (n, m).
Föreläsning I07 38 Prims algoritm, exempel b 3.0 e 5.0 8.0 a 8.0 c 0.0 f 7.0 8.0.0 d.0 g Träd a Prioritetskö < a, b, 5.0 >< a, d, 7.0 >< a, c, 8.0 > b 5.0 a < b, e, 3.0 >< a, d, 7.0 >< a, c, 8.0 >
Föreläsning I07 39 Prims algoritm, exempel, forts. b 3.0 e 5.0 8.0 a 8.0 c 0.0 f 7.0 8.0.0 d.0 g Träd 5.0 a b 3.0 e Prioritetskö < b, e, 3.0 >< a, d, 7.0 >< a, c, 8.0 > b 3.0 e 5.0 a 7.0 < a, d, 7.0 >< a, c, 8.0 >< e, c, 8.0 > d
Föreläsning I07 0 Prims algoritm, exempel, forts. Träd b 3.0 e Prioritetskö 5.0 a < d, g,.0 >< d, f, 8.0 >< a, c, 8.0 > < e, c, 8.0 > 7.0 d b 3.0 e 5.0 a 7.0 < g, f,.0 >< d, f, 8.0 >< a, c, 8.0 > < e, c, 8.0 > d.0 g
Föreläsning I07 Prims algoritm, exempel, forts. Träd b 3.0 e Prioritetskö 5.0 a f < d, f, 8.0 >< a, c, 8.0 >< f, c, 0.0 > < e, c, 8.0 > 7.0.0 d.0 g b 3.0 e 5.0 a 7.0 8.0 c f.0 < f, c, 0.0 >< e, c, 8.0 > < e, c, 8.0 > d.0 g
Föreläsning I07 Kortaste vägen Kortaste vägen mellan två noder i en graf är den väg där summan av bågarnas vikter är den minsta A B 3 C 7 D E G F 5
Föreläsning I07 3 Kortaste vägen, forts. Dijkstras algoritm för att hitta kortaste vägenmellan två noder i en graf ger i själva verket kortaste vägen från utgångspunkten till alla andra noder i grafen. Algoritmen använder sig av en mängd för utvalda noderoch en array för vikterna Vikterna representerar den kortaste vägen mellan utgångspunkten och noden n som passerarnoder i nodmängden
Föreläsning I07 Dijkstras algoritm // Hittar kortaste vägen från en viss utgångspunkt, nod 0 och // alla andra noder i den viktade och riktade grafen mingraf // Arrayen vikt innehåller mingrafs vikter, som är icke-negativa kortaste(mingraf, vikt) { // Steg : initiering Skapa en mängd nodmängd som bara innehåller noden 0 n = antal noder i minvikt[v] = matrix[0][nod] g // Steg : upp till n // Om nod inte finns i nodmängden, så är vikt[nod] den // kortaste vägen av alla vägar från 0 till nod som endast // passerar genom noder som finns i nodmängden // Om nod finns i nodmängden så är vikt[nod] den kortaste av // alla vägar från 0 till nod (inklusive vägar som finns // utanför nodmängden och kortaste vägen från 0 till nod
Föreläsning I07 5 Dijkstras algoritm // finns helt och hållet i nodmängden for (steg = s through n) { Hitta kortaste vägen vikt[nod] där nod inte finns i nodmängden Lägg till v i nodmängden } // Undersök vikt[i] för alla i som inte finns i nodmängden for (alla noder i som inte finns i nodmängden) { if (vikt[i] > vikt[nod] + matrix[nod][i]) { vikt [i] = vikt[nod] + matrix[nod][i] } }
Föreläsning I07 6 Dijkstras algoritm 8 0 9 3 3 Steg Nod Nodmängd [0] [] [] [3] [] -- 0 0 8 9 0, 0 8 5 9 3 0,, 0 7 5 8 0,,, 0 7 5 8 5 3 0,,,,3 0 7 5 8
Föreläsning I07 7 Dijkstras algoritm 8 0 9 3 3 0 0 3 0 8 9 3 3 7