Föreläsning Datastrukturer (DAT036)

Relevanta dokument
Föreläsning Datastrukturer (DAT037)

Föreläsning 8 Datastrukturer (DAT037)

Föreläsning 8 Datastrukturer (DAT037)

Föreläsning 7 Datastrukturer (DAT037)

Föreläsning Datastrukturer (DAT036)

Föreläsning Datastrukturer (DAT037)

Föreläsning Datastrukturer (DAT036)

Föreläsning Datastrukturer (DAT036)

Föreläsning 5: Grafer Del 1

Lösningsförslag för tentamen i Datastrukturer (DAT037) från

Föreläsning 4 Datastrukturer (DAT037)

Föreläsning 4 Datastrukturer (DAT037)

Datastrukturer. föreläsning 9. Maps 1

Lösningsförslag för tentamen i Datastrukturer (DAT036) från

Trädstrukturer och grafer

Tentamen Datastrukturer (DAT036)

Föreläsning 6 Datastrukturer (DAT037)

Grafer MST Top. sortering Starkt samm. komponenter Kortaste avstånd. Grafalgoritmer 1. Douglas Wikström KTH Stockholm

Datastrukturer. föreläsning 9. Maps 1

Tentamen Datastrukturer (DAT036)

Föreläsning 5: Giriga algoritmer. Kruskals och Prims algoritmer

Föreläsning Datastrukturer (DAT036)

Datastrukturer. föreläsning 8. Maps 1

Grafer, traversering. Koffman & Wolfgang kapitel 10, avsnitt 4

Tentamen Datastrukturer (DAT036/DAT037/DIT960)

Föreläsning 5: Giriga algoritmer. Kruskals och Prims algoritmer

Lösningar Datastrukturer TDA

Föreläsning 9 Datastrukturer (DAT037)

Datastrukturer. föreläsning 8. Lecture 6 1

Grafer, allmänt. Med datastrukturen graf menas vanligen: en mängd av noder (vertices) och en mängd av bågar (edges).

Föreläsning Datastrukturer (DAT037)

Lösningsförslag till tentamen Datastrukturer, DAT037,

Föreläsning 13 Datastrukturer (DAT037)

Graphs (chapter 14) 1

Datastrukturer, algoritmer och programkonstruktion (DVA104, HT 2014) Föreläsning 5

Datastrukturer. föreläsning 10. Maps 1

Föreläsning 6 Datastrukturer (DAT037)

Dugga Datastrukturer (DAT036)

Föreläsning 10 Datastrukturer (DAT037)

Tentamen Datastrukturer (DAT036)

Prov i DAT 312: Algoritmer och datastrukturer för systemvetare

Lösningsförslag till tentamen Datastrukturer, DAT037 (DAT036), Tiden det tar att utföra en iteration av loopen är oberoende av värdet på

Tentamen Datastrukturer, DAT037 (DAT036)

Föreläsning 13 Datastrukturer (DAT037)

Föreläsning 10. Grafer, Dijkstra och Prim

Föreläsning 10. Grafer, Dijkstra och Prim

Datastrukturer och Algoritmer D0041D

Algoritmer, datastrukturer och komplexitet

Lösningsförslag till tentamen Datastrukturer, DAT037,

Föreläsning Datastrukturer (DAT037)

Föreläsning Datastrukturer (DAT036)

Föreläsning 10. Grafer, Dijkstra och Prim

Tentamen Datastrukturer (DAT036)

Algoritmer, datastrukturer och komplexitet

Föreläsning 5 Datastrukturer (DAT037)

Träd Hierarkiska strukturer

Föreläsning 3 Datastrukturer (DAT037)

Linjärt minne. Sammanhängande minne är ej flexibelt. Effektivt

Föreläsning Datastrukturer (DAT036)

TDDI16 Datastrukturer och algoritmer. Algoritmanalys

FÖRELÄSNING 11 DATALOGI I

Programmering i C++ EDA623 Dynamiska datastrukturer. EDA623 (Föreläsning 11) HT / 31

Tentamen Datastrukturer (DAT036)

Föreläsning 1 Datastrukturer (DAT037)

Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6

Datastrukturer. Föreläsning 5. Maps 1

Tentamen Datastrukturer (DAT037)

Tentamen Datastrukturer för D2 DAT 035

Tentamen Datastrukturer, DAT037 (DAT036)

Datastrukturer. föreläsning 7. Maps 1

Namn: (Ifylles av student) Personnummer: (Ifylles av student) Tentamensdatum: Tid: Hjälpmedel: Inga hjälpmedel

ORDINARIE TENTAMEN I DATASTRUKTURER OCH ALGORITMER DVG B kl. 08:15 13:15

TNK049 Optimeringslära

Tentamen'('Datastrukturer,'algoritmer'och'programkonstruktion.'

Föreläsning 4: Giriga algoritmer. Giriga algoritmer

Träd. Rot. Förgrening. Löv

TDDI16 Datastrukturer och algoritmer. Prioritetsköer, heapar, Union/Find

TENTAMEN: Algoritmer och datastrukturer. Läs detta!

Föreläsning 1. Introduktion och sökning i graf. Vad är en algoritm?

Föreläsning 2: Grafer. Exempel på graf

OMTENTAMEN I DATASTRUKTURER OCH ALGORITMER DVG B kl. 08:15 13:15

Programmering i C++ EDAF30 Dynamiska datastrukturer. EDAF30 (Föreläsning 11) HT / 34

F11. Läsanvisning: kap 10 + dessa OH. Kruskals algoritm kortaste vägar en till alla

Föreläsning 7. Träd och binära sökträd

Träd, binära träd och sökträd. Koffman & Wolfgang kapitel 6, avsnitt 1 4

Föreläsning 3 Datastrukturer (DAT037)

Föreläsningsanteckningar F6

DAI2 (TIDAL) + I2 (TKIEK)

Algoritmer, datastrukturer och komplexitet

Föreläsning 9 Innehåll

Föreläsning 11 Datastrukturer (DAT037)

Föreläsning 13. Träd

Tentamen, Algoritmer och datastrukturer

TENTAMEN: Algoritmer och datastrukturer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

Tentamen i Algoritmer & Datastrukturer i Java

Näst nästa gång: Nästa gång: mer grafer (kap 10) Grafer 1 1. ! uppspännande träd. ! minimala uppspännande träd. ! Prims algoritm. !

Kapitel 9: Grafalgoritmer

Datastrukturer. Sammanfattning och Referenshäfte. Guldbrand, Eric Johansson, Algot

Tentamen Datastrukturer D DAT 036/INN960

Transkript:

Föreläsning Datastrukturer (DAT036) Nils Anders Danielsson 2013-11-18

Idag Mer om grafer: Minsta uppspännande träd (för oriktade grafer). Prims algoritm. Kruskals algoritm. Djupet först-sökning.

Cykel i oriktad graf Väg av längd 1 som använder varje kant max en gång.

Träd (utan rot) Sammanhängande, acyklisk, oriktad graf.

Uppspännande träd Träd som är delgraf och innehåller alla noder. Minsta uppspännande träd (MST) Uppspännande träd vars totala (kant)vikt är vikten av alla andra uppspännande träd.

Minsta uppspännande träd Några tillämpningar: Konstruktion av nätverk. Klusteranalys. Bildsegmentering. Och mycket annat.

Minsta uppspännande träd Några egenskaper: Existerar omm grafen är sammanhängande. Lägger man till en kant får man en cyklisk graf med exakt en cykel. Tar man sedan bort en kant från cykeln får man ett uppspännande träd.

Prims algoritm (för icketom graf) Done = new set containing arbitrary node s ToDo = V { s } T = new empty set // MST för noder i Done. while ToDo is non-empty do if no edge connects Done and ToDo then raise error: graph not connected (u,v) = cheapest edge connecting Done and ToDo (u Done, v ToDo) Done = Done { v } ToDo = ToDo { v } T = T { (u,v) } return T // Bara kanterna.

Prims algoritm Väldigt lik Dijkstras algoritm. Båda giriga algoritmer. Lägger till billigaste nya noden. Dijkstra: Minsta avståndet från startnoden. Prim: Minsta avståndet från gammal nod.

Prims algoritm: korrekthet Algoritmen ger ett uppspännande träd eller, om grafen ej är sammanhängande, ett felmeddelande: Invariant: T är ett uppspännande träd för noderna i Done. Invarianten håller i början: Trädet med noden s och inga kanter spänner upp { s }. Invarianten bevaras: Lägger alltid till ny nod, aldrig cykel. (Om felmeddelande: ej sammanhängande.) När vi kör return T så är Done = V. Läs själva

Prims algoritm: korrekthet Algoritmen ger ett MST (om det finns något): Invariant: T är ett delträd av något MST. Invarianten håller i början: Det tomma trädet är ett delträd av alla MST. Invarianten bevaras: Antagande: T är ett delträd av något MST. Visa (för k = (u, v)): T { k } är ett delträd av något MST. Läs själva

Prims algoritm: korrekthet Antagande: T delträd av MST M. Visa: T { k } delträd av något MST. Klara om k M. Annars finns cykel C med k C och C { k } M. Betrakta mängden K = C (T { k }). k förbinder Done och ToDo, T gör det inte, C är en cykel en kant k K förbinder Done och ToDo. k är minst lika dyr som k. T { k } delträd av (M { k }) { k } (som är ett MST). Läs själva

Hemuppgift för intresserade Visa att Dijkstras algoritm är korrekt.

Prims algoritm Kan implementera Prims algoritm på ungefär samma sätt som Dijkstras. (Glöm inte kontrollera att grafen är sammanhängande.) Tidskomplexitet: O( V 2 ). O( E log V ) (om V = O( E )).

Vad är den totala vikten av följande två grafers minsta uppspännande träd? 4 2 5. 1 6 3 10 11 9 1 8 3 7 4. 2 5 6

Kruskals algoritm Välj hela tiden billigaste kanten som inte skapar en cykel.

Kruskals algoritm Hur hittar vi billigaste kanten? Prioritetskö? Hur vet vi om kanten skapar en cykel?

Disjunkt mängd-adtn Representerar partition av ändlig mängd. new disjoint-set(n): Skapar { { i } i { 0, 1,, n 1 } }. union: Slår ihop två delmängder. find: Ger unik representant för delmängd. find(i) == find(j) omm i och j hör till samma delmängd.

Disjunkt mängd-datastruktur En implementation (se boken): new disjoint-set(n): Θ(n). union: Nästan konstant amorterad tid. find: Nästan konstant amorterad tid.

Kruskals algoritm if V <= 1 then return empty set Partition = new disjoint-set( V ) Edges = new priority queue containing E, prioritised by edge weight T = new empty set while Edges is non-empty do (u,v) = Edges.delete-min() if Partition.find(u)!= Partition.find(v) then Partition.union(u,v) T = T { (u,v) } if T == V - 1 then return T raise error: graph not connected

Vad är värstafallstidskomplexiteten för Kruskals algoritm? (Anta att Edges är en binär heap och T en lista. Anta inte att V = O( E ).) Θ( V + E ). Θ( E log V ). Θ( V + E log V ). Θ(( V + E ) log V ). Θ( V E ). Hemuppgift för intresserade Visa att Kruskals algoritm är korrekt.

Kruskals algoritm if V <= 1 then return empty set Partition = new disjoint-set( V ) Θ( V ) Edges = new priority queue containing E, Θ( E ) prioritised by edge weight T = new empty set while Edges is non-empty do (u,v) = Edges.delete-min() O( E ) ggr O(log V ) if Partition.find(u)!= Partition.find(v) then Partition.union(u,v) T = T { (u,v) } if T == V - 1 then return T raise error: graph not connected

Djupet förstsökning

Djupet först-sökning (DFS) Metod för att gå igenom alla noder och kanter. Har tidigare sett bredden först-sökning. Fungerar för oriktade och riktade grafer.

Djupet först-sökning: mall visited = new array with indices {0,, V -1} and all elements equal to false // Startar/startar om sökning. for v {0,, V -1} do if not visited[v] then dfs(v) // Utför sökning. dfs(v) { visited[v] = true } for w {w (v, w) E} do if not visited[w] then dfs(w)

Djupet först-sökning: mall visited = new array with indices {0,, V -1} and all elements equal to false O( V ) // Startar/startar om sökning. for v {0,, V -1} do if not visited[v] then dfs(v) // Utför sökning. dfs(v) { visited[v] = true O( V ) ggr O( V ) ggr } for w {w (v, w) E} do if not visited[w] then dfs(w) O( E ) ggr

Djupet först-sökning Tidskomplexitet: O( V + E ) (linjär).

Uppspännande skog Depth-first spanning forest: Skog: Lista av träd. Ett träd för varje toppnivåanrop till dfs. Rekursiva anrop till dfs ger upphov till vanliga trädkanter. Om visited[w] = true får man istället en speciell kant: Bakåtkant: Om kanten pekar uppåt. Framåtkant: Om kanten pekar nedåt. Tvärkant: I övriga fall ( åt vänster ).

Uppspännande skog Graf: 1. 0 2 4 3 Skog (om vi söker från 0, 1 och 4, och väljer 2 före 3): 0. 1 4 5 2 5 3

Hur många bakåtkanter innehåller DFS-skogen för följande graf, givet att vi, då vi kan välja mellan flera noder, alltid väljer den lägst numrerade noden? 1 6.0. 2 3 4 5

Djupet först-sökning DFS kan användas för att implementera andra algoritmer. Exempel: Är en oriktad graf sammanhängande? Testa om DFS från godtycklig nod besöker alla noder (utan omstart).

Sammanhängande? if V = 0 then return true visited = new array with indices {0,, V -1} and all elements equal to false dfs(0) for v {1,, V -1} do if not visited[v] then return false return true dfs(v) { visited[v] = true for w {w (v, w) E} do if not visited[w] then dfs(w) }

Djupet först-sökning Återanvändning genom kopiering? Mer modulärt: dfs :: Graph -> Forest type Forest = [Tree] type Vertex = Integer data Tree = Root Vertex [Edge] data Edge = Regular Tree Forward Vertex Back Vertex Cross Vertex Olika implementationer av dfs för oriktade och riktade grafer.

Djupet först-sökning Modulär implementation: connected :: Graph -> Bool connected g = length (dfs g) <= 1 Kanske mindre effektiv. Är grafen cyklisk? cyclic :: Graph -> Bool cyclic g = hasbackedge (dfs g)

Träd: traverseringsordningar Kan gå igenom ett träds noder i olika ordning: Preorder Roten, barnträden från vänster till höger, vart och ett i preorder. Postorder Barnträden från vänster till höger, roten. Inorder För binära träd: vänster barnträd, roten, höger barnträd. Kan generaliseras från träd till skogar (vänster till höger).

Topologisk sortering Kan sortera DAG topologiskt genom att utföra DFS och pusha noderna på stack i postordning: -- Precondition: Grafen måste vara acyklisk. topologicalsort :: Graph -> [Vertex] topologicalsort g = postorderpush (dfs g)

Starkt sammanhängande komponenter För riktade grafer: Starkt sammanhängande graf: Om u, v V så finns det en väg från u till v (och vice versa). Starkt sammanhängande komponent (SCC): Maximal starkt sammanhängande delgraf. Om varje SCC byts ut mot en ny nod (en per SCC) får vi en multi-dag.

Starkt sammanhängande komponenter Exempel: Noder: Funktioner. Kanter: Anrop från en funktion till en annan. Funktioner i en SCC är ömsesidigt rekursiva.

Hur många starkt sammanhängande komponenter innehåller följande graf? 1 6.0. 2 3 4 5.7. 8 9

SCC-algoritm Kan vi hitta alla SCCer? Kan hitta alla noder i löv-scc genom DFS (utan omstart) från någon av dem. Kan sedan ta bort (ignorera) löv-sccn och fortsätta med annan löv-scc. Men hur hittar man löv-sccer?

SCC-algoritm Utför DFS, lägg noder på stack i postordning. Översta noden (om någon) måste höra till en rot-scc. Tar man bort alla noder som hör till den SCCn så hör översta noden (om någon) återigen till en rot-scc. Och så vidare För löv-scc: Utför DFS baklänges (på reverserad graf).

SCC-algoritm 1. Utför DFS baklänges, pusha noder i postordning. 2. Utför DFS framlänges, börja hela tiden med översta obesökta stacknoden. Varje sökning ger en SCC.

SCC-algoritm -- Börja varje sökning i den första obesökta -- listnoden. ordereddfs :: Graph -> [Vertex] -> [Tree] -- Reverserar grafen. opposite :: Graph -> Graph -- Resultatet är omvänt topologiskt sorterat. sccs :: Graph -> [[Vertex]] sccs g = map verticesintree (ordereddfs g stack) where stack = postorderpush (dfs (opposite g))

SCC-algoritm Tidskomplexitet: O( V + E ).

Sammanfattning Minsta uppspännande träd. Djupet först-sökning. Nästa vecka: Sökträd.

Ge valfri feedback på hur kursen fungerar