Grafalgoritmer
Vi skal se på grafalgoritmer for: raversering: Nåbarhet: Oppsøk alle nodene i grafen en og bare en gang, på en eller annen systematisk måte innes det en vei fra en node til en annen node? Korteste vei: Hvor lang er den korteste veien mellom par av noder i en vektet graf?
raversering av grafer raversering (kalles også søking i grafen ): Gå innom/søke opp alle noder i grafen en og bare en gang Problemer ved graftraversering: Det er ofte ingen rot eller naturlig startpunkt i en graf Grafen kan være cyklisk slik at en node oppsøkes flere ganger Grafen kan være usammenhengende eller svakt sammenhengede, slik at ikke alle noder kan nås fra en gitt node
DS og BS o standard rekkefølger for traversering av grafer: DS: Dybde-først søk (Depth-irst Search) BS: Bredde-først søk (Breadth-irst Search) elles for begge traverseringsmetoder: Starter med en første node som markeres oppsøkt Går deretter videre til sist oppsøkte nodes uoppsøkte naboer, på en eller annen systematisk måte raversering med nabomatrise er alltid O(n²)
orskjellen på DS og BS Dybde-først: Går rekursivt direkte videre til første uoppsøkte node Vil gå i dybden langs veier med uoppsøkte noder Bredde-først: Lagrer uoppsøkte noder i en (IO) kø De uoppsøkte nodene nærmest startnoden oppsøkes først Søkingen brer seg i ringer fra utgangspunktet
raversering: Eksempel Urettet graf, starter i node Uoppsøkte naboer oppsøkes i stigende rekkefølge DS: BS:
raversering: Eksempel Rettet graf, starter i node Uoppsøkte naboer oppsøkes i stigende rekkefølge DS: BS:
raversering: Eksempel Urettet graf, starter i node A Uoppsøkte naboer oppsøkes i alfabetisk rekkefølge DS: A D M E B C I G K J P O Q L H N BS: A D M B C E H Q I J L N G K P O
Animasjon av DS og BS
Mer animasjon av DS og BS Med muligheter for å variere: Rettet/urettet graf Størrelsen på eksempelgrafen remvisning av grafen: Med noder som sirkler og kanter som linjer/piler Som nabolister Som nabomatrise Dybde-først søk Bredde-først søk
raversering og spenn-trær * Spenn-tre: I læreboka: Et tre som består av alle nodene i en graf og et utvalg av kantene, slik at alle nodene er forbundet Algoritme for å finne spenn-treet med minst total veilengde (minimum spanning tree) i en vektet graf Kantene som følges i en traversering, vil alltid utgjøre et spenn-tre: Dybde-først: Spenn-treet blir høyt og ubalansert Bredde-først: Lavere, mer balansert spenn-tre * Engelsk: spanning tree
Spenntrær for DS og BS
Dybde-først søk: Algoritme DS implementeres naturlig rekursivt: DS(node x) { oppsøk(x) for hver node y som er nabo med x hvis y ikke er oppsøkt DS(y) } Læreboka implementerer grafer som en generisk AD med en ikke-rekursiv DS-iterator som bruker en stack
Bredde-først søk: Algoritme BS implementeres iterativt med bruk av en kø: BS(node start) { enqueue(start) så lenge kø ikke tom { x = dequeue() oppsøk(x) for hver node y som er nabo med x hvis y ikke er oppsøkt eller ligger i kø enqueue(y) } } Læreboka implementerer en generisk BS-iterator
Enkel implementasjon av DS og BS Utvider klassen enkelgraf.java med metoder for dybde-først og bredde-først traversering DS: Rekursiv Bruker boolsk array til å merke noder som er oppsøkt BS: Bruker lærebokas kømodul Boolsk array merker noder som er oppsøkt eller i kø Java-kode: traversergraf.java
Nåbarhet * En node er nåbar fra en annen node hvis det finnes en vei i grafen mellom de to nodene En vanlig problemstilling for grafer er å finne ut hvilke noder som er innbyrdes nåbare kan vi reise fra A til B? Bestemmelse av nåbarhet kan også brukes til å avgjøre om en graf er (sterkt eller svakt) sammenhengende *: Engelsk: Reachability
o standardproblemer for nåbarhet i grafer SSRP Single Source Reachability Problem : inn alle noder som er nåbare fra en bestemt node APRP All-Pairs Reachability Problem inn alle noder som kan nås fra enhver node i grafen
Single Source Reachability Problem Alle noder nåbare fra :,, Enkel O(n²) løsning på SSRP: Gjør en dybde-først eller bredde-først traversering fra startnoden Alle noder som oppsøkes i traverseringen er nåbare
All-Pairs Reachability Problem Alle noder nåbare fra: :,, :,,,, :,,,, :,, :,, :,,
Enkel løsning av APRP raversér grafen n ganger (med DS eller BS), én gang med start i hver node i grafen Denne løsningsmetoden er alltid O(n³) hvis grafen er lagret med nabomatrise Kan også brukes for å teste konnektivitet: Hvis alle traverseringene er innom alle n noder, er grafen (sterkt) sammenhengende Implementasjon: traversergraf.java
Løsningsmatrise for APRP Løsningen på APRP kan representeres som en boolsk matrise/-d tabell A, der A[ i ] [ j ] er true hvis og bare hvis det går en vei fra node i til node j
Løsningsmatrise og nabomatrise Løsningsmatrisen for APRP kan betraktes som en utbygging av nabomatrisen for grafen Nabomatrise Løsningsmatrise
Warshall-algoritmen* Løser APRP ved å transformere nabomatrisen til løsningsmatrisen Bruker følgende prinsipp: Det finnes en vei fra node i til node j, hvis det finnes en vei fra node i til node k, og fra node k til node j Algoritmen bygger stegvis ut nabomatrisen med alle mulige veier mellom alle par av noder Etter n steg vil garantert alle veier i hele grafen ligge lagret i løsningsmatrisen *: Warshall, Stephen: "A theorem on Boolean matrices", Journal of the ACM, 9
Warshall: Stegvis løsning Steg : inn alle veier av lengde Steg : inn alle veier av lengde... Steg n: Alle veier funnet Nabomatrise Løsningsmatrise etter to steg
Warshall-algoritmen: Effektivitet og implementasjon Programmeres enkelt med tre løkker: Ytre løkke går n ganger, i hvert steg finnes alle veier av lengde,,,... o indre løkker som går gjennom hele nabomatrisen og kobler node i og j hvis begge har en vei til node k Warshall er alltid O(n³) for graf lagret i nabomatrise Enkel implementasjon: warshall.java
Uvektet, rettet graf for testing av APRP-metoder il: graf_.txt
Korteste-vei problemer for vektede grafer * Single Source Shortest Path Problem inn lengden av korteste vei fra én bestemt node til alle andre noder i grafen All-Pairs Shortest Path Problem inn lengden av korteste vei fra alle noder til alle andre noder i grafen *: or uvektede grafer finnes korteste veier enkelt med bredde-først søk
Anvendelser av korteste-vei algoritmer Ruteplanlegging GPS Google Maps ravelling Salesman's Problem låtestyring Ulike typer optimaliseringer Og veldig mye mer...
Vektede grafer for korteste-vei problemer Representerer grafen som en nabomatrise med kantlengder Hvis det ikke går en kant mellom to noder, legger vi inn en uendelig stor kantlengde 8
All-Pairs Shortest Path inn lengden av korteste vei mellom alle par av noder Kan løses ved å transformere nabomatrisen til en løsningsmatrise med korteste veilengder 9 8 7 7 9 8 7 8
loyds algoritme * Starter med nabomatrisen, bygger opp løsningsmatrisen steg for steg Samme prinsipp som i Warshall-algoritmen: Det finnes en vei fra node i til node j, hvis det finnes en vei fra node i til node k, og fra node k til node j Sjekker alle mulige veier, tar hele tiden vare på den korteste veien som til nå er funnet mellom to noder I hvert steg øker antall noder langs veiene med Etter n steg vil garantert lengden til alle de korteste veiene i hele grafen ligge lagret i løsningsmatrisen *: loyd, Robert W.: "Algorithm 97: Shortest Path", Communications of the ACM, 9
loyd: Stegvis løsning Steg : Steg : inn alle korteste veier med maks. noder inn alle korteste veier med maks noder 9 8 7 7 9 8 7 Steg n : Alle korteste veier funnet 8
Animasjon av loyd s algoritme Med muligheter for å variere: Rettet/urettet graf Størrelsen på eksempelgrafen remvisning av grafen: Med noder som sirkler og kanter som linjer/piler Som nabolister Som nabomatrise loyd-warshall All-Pairs Shortest Path
loyds algoritme: Effektivitet og implementasjon Programmeres enkelt med tre løkker, på samme måte som Warshall-algoritmen: Ytre løkke går n ganger, i hvert steg finnes alle de korteste veiene med,,, noder o indre løkker som går gjennom hele nabomatrisen og kobler node i og j hvis begge har en vei til node k loyd er alltid O(n³) for graf lagret i nabomatrise Enkel implementasjon: floyd.java
Single Source Shortest Path inn lengden av korteste vei fra én bestemt node til alle andre noder i grafen Kan løses med Dijkstras algoritme * Standard algoritme i mange systemer, f.eks. GPS-enheter, Google Maps, flybillettbestilling, ruting av av data på internett... *: Dijkstra, Edsger. W.: "A note on two problems in connexion with graphs", Numerische Mathematik, 99
Dijkstras algoritme Anvendes på en vektet graf med n noder Starter i en node S, finner korteste avstand fra S til alle andre noder Bruker maksimalt n steg, i hvert steg finner vi den korteste avstanden fra S til én ny node i grafen Ligner mye på et bredde-først søk Basert på følgende prinsipp: Den korteste veien fra S til en ny node må gå langs en av de korteste veiene til en av den nye nodens naboer
Dijkstra: Ekstra datastruktur En boolsk array funnet av lengde n: Alle elementer er intitielt lik false Brukes til å merke nodene som vi allerede har funnet korteste vei til En array avstand med n veilengder: Lagrer den hittil korteste veien som vi til nå har sett fra startnoden S til alle andre noder i grafen Alle elementer er lik uendelig til å begynne med, unntatt for startnoden der korteste vei settes lik Løsningen ligger i arrayen avstand når algoritmen er ferdig
s= funnet = avstand = y= t= x= z= { true, true, false, false, false } {,,,, }
Dijkstras algoritme: Animasjon (finner korteste vei fra a til b)
Dijkstras algoritme: Eksempel
Dijkstra: Algoritme funnet[i] = false, i =,,,..., n avstand[i] =, i =,,,..., n avstand[s] = denne = S antall = or (alle naboer i til denne, der funnet[i] == false) { l = avstand[denne] + kantlengde[denne][i] Hvis (l < avstand[i]) avstand[i] = l funnet[denne] = true antall++ Hvis antall == n: Avslutt denne = (noden som har minst verdi av avstand og der funnet[denne] == false) }
Dijkstras algoritme: Animasjon Kantene i figuren er tegnet like lange som vekten/kantlengden
Mer animasjon av Dijkstra Med muligheter for å variere: Rettet/urettet graf Størrelsen på eksempelgrafen remvisning av grafen: Med noder som sirkler og kanter som linjer/piler Som nabolister Som nabomatrise Dijkstra Shortest Path
Dijkstra: Effektivitet og implementasjon Er O(n) i originalutgaven, for en graf med n noder Blir O(n log n) med smartere koding (øvingsoppgave): Bruk en min-heap for å lagre avstandene Søking etter noden med minst avstand blir da O(log n) Er litt fiklete fordi vi må justere heapen hver gang avstander oppdateres i grafen Dijkstra kan også løse all-pairs shortest path: Start algoritmen én gang fra hver node i grafen Enkel O(n) implementasjon: dijkstra.java
Dijkstra: Lagring av korteste veier Et problem med denne versjonen av Dijkstra er at det bare er lengden på de korteste veiene til hver node som tas vare på Ofte vil vi også ha behov for å vite hvilke noder den korteste veien går innom (se eksempel neste side) Øvingsoppgave: Programmering av en versjon av Dijkstra som både lagrer de korteste avstandene og veiene
Vektet, rettet graf for testing il: vgraf_.txt