Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

Grafalgoritmer II.

Lignende præsentationer


Præsentationer af emnet: "Grafalgoritmer II."— Præsentationens transcript:

1 Grafalgoritmer II

2 Plan Vægtede grafer minimalt udspændende træ korteste vej Orienterede grafer transitiv afslutning alle korteste veje topologisk sortering

3 Vægtede grafer En vægtet graf indeholder kanter med tilknyttede talværdier, vægte. Vægtene kan f.eks. være udtryk for afstande eller omkostninger. A B 7 Minimalt udspændende træ: Find den “billigste” måde at forbinde alle knuder i en graf. Korteste vej: Find den “billigste” vej mellem to knuder.

4 Eksempel på vægtet graf
B C G F D E H I J K L M 1 2 6 3 5 4 Repræsentation: Nabomatrix: erstat boolske værdier med vægte. Nabolister: tilføj et felt, w, til hvert listeelement: class Node { int v; Node next; int w; } I det følgende betragtes kun grafer med positive vægte.

5 Nabomatrix . . . Naboliste . a: A B C G F D E H I J K L M 1 2 6 3 5 4
A B C D E F G H I J K L M A B C D E F G H I J K L M a: Nabomatrix B 1 z A C adj: . . . . F 2 G 6 Naboliste

6 Klassedeling af knuder
I algoritmerne skelnes mellem 3 typer af knuder: (1) Træknuder (besøgte knuder) (2) Randknuder (knuder, der støder op til træknuder, men som endnu ikke er besøgt) (3) Usete knuder (alle andre knuder) Træknuder Rand Usete

7 Bedste-først-søgning (priority-first search)
Anvend en prioritetskø, pq (i stedet for en stak eller en kø). Træknuder (TREE): besøgte knuder Randknuder (FRINGE): ubesøgte knuder forbundet med en kant til træknuder Usete knuder (UNSEEN): alle andre knuder Sæt alle knuders status til UNSEEN. Læg en knude i pq og sæt dens status til FRINGE. Så længe pq ikke er tom: Fjern den “bedste” knude, k, fra pq. Sæt k’s status til TREE. For enhver af k’s naboknuder: hvis UNSEEN, så læg den i pq og sæt dens status til FRINGE, hvis FRINGE, så opdater dens prioritet.

8 Antag at pq er en prioritetskø ordnet efter stigende prioritet.
void search() { for (int k = 1; k <= V; k++) status[k] = UNSEEN; id = 0; visit(1); } void visit(int k) { pq.insert(k, 0); status[k] = FRINGE; while (!pq.empty()) { id++; k = pq.remove(); status[k] = TREE; for (Node t = adj[k]; t != z; t = t.next) if (status[t.v] == UNSEEN) { pq.insert(t.v, priority); status[t.v] = FRINGE; } else if (status[t.v] == FRINGE) pq.update(t.v, priority); } } Antag at pq er en prioritetskø ordnet efter stigende prioritet. priority = id: Bredde-først-søgning (Kø) priority  -id: Dybde-først-søgning (Stak)

9 Ændret udgave visited[k] status[k] == TREE)
void search() { for (int k = 1; k <= V; k++) visited[k] = false; id = 0; visit(1); } void visit(int k) { pq.insert(k, 0); while (!pq.empty()) { id++; k = pq.remove(); visited[k] = true; for (Node t = adj[k]; t != z; t = t.next) if (!visited[t.v]) pq.update(t.v, priority); } Metoden update indsætter en knude i prioritetskøen, hvis den ikke er der i forvejen. Knudens prioritet ændres, hvis der er tale om en “forbedring”.

10 Minimalt udspændende træ
En minimalt udspændende træ (MST) er en samling af grafens kanter, der forbinder alle knuder i grafen, og som har en mindst mulig sum af vægte. A B C G F D E H I J K L M 1 2 6 3 5 4 Vægtsum: = 14 Et minimalt udspændende træ behøver ikke at være unikt.

11 Bestemmelse af MST Hovedsætning: Opdel knuderne i grafen i to mængder, A og B. Så vil den korteste kant X, der forbinder en knude i A med en knude i B, tilhøre MST. X A B Bevis (ved modstrid): Hvis X ikke er i MST, så tilføj den til MST * herved skabes en cykel * en anden kant Y fra A til B må være på denne cykel * sletning af Y og tilføjelse af X giver et kortere træ

12 Bedste-først-søgning til bestemmelse af MST
Mængde A: besøgte knuder Mængde B: ubesøgte knuder Korteste kant, der forbinder A med B, må tilhøre MST. void visit(int k) { pq.insert(k, 0); dad[k] = 0; while (!pq.empty()) { k = pq.remove(); visited[k] = true; for (Node t = adj[k]; t != z; t = t.next) if (!visited[t.v] && pq.update(t.v, t.w)) dad[t.v] = k; } update returnerer true, hvis knuden ikke findes i pq, eller hvis den tildeles en lavere prioritet.

13 Bestemmelse af MST i lærebogen
void visit(int k) { if (pq.update(k, -unseen)) dad[k] = 0; while (!pq.empty()) { k = pq.remove(); val[k] = -val[k]; if (val[k] == -unseen) val[k] = 0; for (Node t = adj[k]; t != z; t = t.next) if (val[t.v] < 0 && pq.update(t.v, t.w)) { val[t.v] = -t.w; dad[t.v] = k; } Knude k i TREE: val[k] > 0 (= weight(k,dad[k])) Knude k i FRINGE: val[k] < 0 (= -weight(k,dad[k])) Knude k i UNSEEN: val[k] = unseen = Integer.MIN_VALUE

14 Eksempel på bestemmelse af MST ved bedste-først-søgning
C G F D E H I J K L M 1 2 6 3 5 4 uset knude randknude træknude trækant uset kant randkant A B C G F D E H I J K L M 1 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4

15 1 A B C G F D E H I J K L M 2 6 3 5 4 2 A B C G F D E H I J K L M 1 6 3 5 4 1 A B C G F D E H I J K L M 2 6 3 5 4

16 2 A B C G F D E H I J K L M 1 6 3 5 4 2 A B C G F D E H I J K L M 1 6 3 5 4 1 A B C G F D E H I J K L M 2 6 3 5 4

17 1 A B C G F D E H I J K L M 2 6 3 5 4 1 A B C G F D E H I J K L M 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4

18 A B C G F D E H I J K L M 1 2 6 3 5 4

19 Effektivitet Bedste-først-søgning i en graf kan bestemme
MST i tid O((V+E)logV). V kald af remove E kald af update Hvis pq er en hob, så er tiden for et kald af remove og for et kald af update O(logV).

20 Kruskals metode (1956) Kanter tilføjes en ad gangen. I hvert skridt tilføjes den korteste kant, der ikke giver anledning til en cykel. A B C G F D E H I J K L M 1 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4

21 A B C G F D E H I J K L M 1 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4

22 A B C G F D E H I J K L M 1 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4

23 A B C G F D E H I J K L M 1 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4

24 Korrekthed følger af hovedsætningen.
B C G F D E H I J K L M 1 2 6 3 5 4 Korrekthed følger af hovedsætningen. A er de knuder, der tilhører et af træerne. B er de øvrige knuder. Implementering: (1) Skal kunne finde den næste (korteste) kant: (a) sorter kanter efter vægt, eller (b) benyt en hob [ bedst ] (2) Skal kunne afgøre om tilføjelse af en kant vil resultere i en cykel: Benyt Foren-og-Find til at afgøre om kantens endeknuder begge tilhører samme træ

25 class Edge { int v1, v2; int w; }
void kruskal() { int V = IO.readInt(), E = IO.readInt(); Edge e[] = new Edge[E]; PQ pq = new PQ(E); EQ eq = new EQ(E); for (int i = 0; i < E; i++) { e[i] = new Edge(); e[i].v1 = IO.readInt(); e[i].v2 = IO.readInt(); e[i].w = IO.readInt(); pq.insert(i, e[i].w); } for (int i = 1; i <= V-1 && !pq.empty(); ) { int m = pq.remove(); if (eq.find(e[m].v1, e[m].v2, true)) { IO.println(e[m].v1 + "," + e[m].v2); i++; }

26 Effektivitet Kruskals algoritme kan bestemme MST i tid
O(E + M logE), hvor M er antallet af kanter i grafen, der er kortere end den længste kant i MST. Tid til inititialsering af hob: O(E). Antal kald af remove : M. Tid for hvert kald af remove: O(logE). Jvf. Bedste-først-søgning i en graf kan bestemme MST i tid O((V+E)logV).

27 Korteste vej (enkelt kilde, korteste-vej-træ, SPT)
Problem: Bestem alle korteste veje fra en knude x til enhver anden knude. Algoritme: benyt bedste-først-søgning startende i x, idet val[k]: korteste afstand fra x til k priority for en randknude, t.v: hidtil korteste afstand fra x til knuden: priority  val[k] + t.w k t.v t.w x val[k]

28 Eksempel på bestemmelse af korteste veje
C G F D E H I J K L M 1 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4

29 A B C G F D E H I J K L M 1 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4 A B C G F D E H I J K L M 1 2 6 3 5 4

30 A B C G F D E H I J K L M 1 2 6 3 5 4 7 A B C G F D E H I J K L M 1 2 6 3 5 4 7 A B C G F D E H I J K L M 1 2 6 3 5 4 7

31 A B C G F D E H I J K L M 1 2 6 3 5 4 8 A B C G F D E H I J K L M 1 2 6 3 5 4 7 8 A B C G F D E H I J K L M 1 2 6 3 5 4 8

32 Bedste-først-søgning i en graf kan bestemme
C G F D E H I J K L M 1 2 6 3 5 4 8 A B C G F D E H I J K L M 1 2 6 3 5 4 Bedste-først-søgning i en graf kan bestemme det korteste-vej-træ i tid O((E+V)logV).

33 MST og SPT i tætte grafer (repræsenteret ved nabo(vægt)matrix)
void search() { int k, t, min = 0; for (k = 1; k <= V; k++) { visited[k] = false; val[k] = Integer.MAX_VALUE; dad[k] = 0; } val[min] = Integer.MAX_VALUE; val[1] = 0; for (k = 1; k != 0; k = min, min = 0) { visited[k] = true; for (t = 1; t <= V; t++) if (!visited[t]) { if (a[k][t] > 0 && priority < val[t]) { val[t] = priority; dad[t] = k; if (val[t] < val[min]) min = t; MST: priority  a[k][t] SPT: priority  val[k] + a[k][t]

34 Effektivitet MST og SPT kan bestemmes i tid O(V2) i tætte grafer.
MST: Prims algoritme (1957) SPT: Dijkstras algoritme (1959) Prims og Dijkstras algoritme er begge eksempler på “grådige” algoritmer.

35 Orienterede grafer En orienteret graf er en graf, hvor hver kant har en retning. Kanterne i en orienteret graf kaldes også for pile. Kan f.eks. benyttes til at modellere ensrettede veje Eller til at modellere afhængighed: løsning af opgave B kan først påbegyndes, når opgave A er løst. B A Repræsentation: Nabomatrix: true/false, alt efter om kanten er med eller ej. Nabolister: hver kant repræsenteres kun én gang.

36 En orienteret graf Skov for dybde-først-søgning: down cross up A B C G
H I J K L M B A C G F E D H I J K L M up cross down Skov for dybde-først-søgning:

37 Problem: Find for enhver knude i en orienteret graf
alle de knuder, der kan nås fra knuden. for (k = 1; k <= V; k++) { for (i = 1; i <= V; i++) visited[i] = false; visit(k); IO.println(); } void visit(int k) { // adjacency lists IO.print(name(k) + ” ”); visited[k] = true; for (Node t = adj[k]; t != z; t = t.next) if (!visited[t.v]) visit(t.v);

38 Resultat A F E D G J K L M C B B C A F E D B G J K L M D F E E D F
H I J K L M A F E D G J K L M C B B C A F E D B G J K L M D F E E D F F E D G J K L M C A F E D B H G J K L M C A F E D B I I H G J K L M C A F E D B J K L G C A F E D B M K L G J K M C A F E D B M L G J K C A F E D B

39 Den transitive afslutning
Den transitive afslutning er den graf, der opstår ved tilføjelse af alle kanter mellem knuder, x og y, for hvilke der findes en vej fra x til y. A B C G F D E Dybde-først-søgning kan benyttes til at bestemme den transitive afslutning for en orienteret graf i tid O(V(V+E)) for tynde grafer, og O(V3) for tætte grafer.

40 Den transitive afslutning for en graf repræsenteret ved nabomatrix
Warshalls algoritme (1962). Udnytter udsagnet: Hvis der er en måde at komme fra x til m, og en måde at komme fra m til y, så er der en måde at komme fra x til y. x m y For at effektivisere beregningerne skærpes udsagnet til: Hvis der er en måde at komme fra x til m, og en måde at komme fra m til y, hvor der i begge tilfælde kun benyttes mellemliggende indices < m, så findes der en måde at komme fra x til y, der kun benytter mellemliggende indices < m+1.

41 Warshalls algoritme Kan effektiviseres ved at flytte testen a[x][m]):
for (m = 1; m <= V; m++) for (x = 1; x <= V; x++) for (y = 1; y <= V; y++) if (a[x][m] && a[m][y]) a[x][y] = true; for (m = 1; m <= V; m++) for (x = 1; x <= V; x++) if (a[x][m]) for (y = 1; y <= V; y++) if (a[m][y]) a[x][y] = true; Kan effektiviseres ved at flytte testen a[x][m]): Kompleksitet: O(V3).

42 Beregningspricippet i Warshalls algoritme
x y 1 a[x] a[m] if (a[x][m] && a[m][y]) a[x][y] = true; if (a[x][m]) a[x][y] = a[x][y] || a[m][y]; if (a[x][m]) a[x] = or(a[x],a[m]);

43 Warshalls algoritme ved brug af class BitSet
for (m = 1; m <= V; m++) for (x = 1; x <= V; x++) if (a[x].get(m)) a[x].or(a[m]); Initialisering: BitSet a[] = new BitSet[V+1]; for (x = 1; x <= V; x++) a[x] = new BitSet(V+1); a[2].set(3); ...

44 Alle korteste veje Floyds algoritme (1962)
Benyt samme struktur som i Warshalls algoritme. for (m = 1; m <= V; m++) for (x = 1; x <= V; x++) if (a[x][m] > 0) for (y = 1; y <= V; y++) if (a[m][y] > 0 && (a[x][y] == 0 || a[x][m] + a[m][y] < a[x][y])) a[x][y] = a[x][m] + a[m][y]; Ikke-eksisterede kanter antages her at have vægten 0. Floyds algoritme bestemmer alle korteste veje i tid O(V3).

45 DAGs En orienteret graf uden cykler kaldes for en DAG (Directed Acyclic Graph). En DAG kan f.eks. benyttes til at modellere et aktivitetsnetværk, hvor pilene angiver, at en aktivitets færdiggørelse er en forudsætning for en andens påbegyndelse.

46 Netværksplanlægning aktivitet forgænger(e) varighed (uger)
A konstruer lagerstyringsmodel B implementer lagerstyringsprogram A C konstruer prognosemodel D implementer prognoseprogram C E indsaml data F design database A G implementer database E, F H oplær personale B, D I afprøv system G, H C D H B E A F G I

47 Dybde-først-søgning i en DAG
C G F D E H I J K L M A J F C B G K L E D H I M En skov for dybde-først-søgning har ingen opadgående kanter.

48 Topologisk sortering En DAG kan ordnes, således at ingen knude kommer før nogen anden knude, der peger på den. Denne operation kaldes topologisk sortering. A B C G F D E H I J K L M Topologisk orden: Alle pile vender samme vej, fra venstre mod højre [ikke unik] J K L M A G H I F E D B C

49 Omvendt topologisk orden
A J F C B G K L E D H I M Omvendt topologisk orden kan opnås ved dybde- først-søgning i grafen. D E F C B I H G A K M L J void visit(int k) { // adjacency lists visted[k] = true; for (Node t = adj[k]; t != z; t = t.next) if (!visited[t.v]) visit(t.v); IO.println(name(k)); // post }

50 En anden algoritme til topologisk sortering
(1) Vælg en knude uden indgående kanter (2) Skriv knuden ud. Fjern knuden og alle dens kanter fra grafen (3) Gentag (1) og (2), indtil der ikke er flere knuder i grafen

51 Implementering i Java Køen q indeholder alle knuder med indgrad 0.
void tologicalOrder() { for (k = 1; k <= V; k++) degree[k] = 0; Node t; for (k = 1; k <= V; k++) for (t = adj[k]; t != z; t = t.next) degree[t.v]++; Queue q = new Queue(); for (k = 1; k <= V; k++) if (degree[k] == 0) q.insert(k); while (!q.empty()) { k = q.remove(); IO.println(name(k)); for (t = adj[k]; t != z; t = t.next) if (--degree[t.v] == 0) q.insert(t.v); } } degree[k] angiver den aktuelle “indgrad” for knuden k. Køen q indeholder alle knuder med indgrad 0.

52 Ugeseddel 10 18. november - 24. november
• Løs følgende opgaver 1. Opgave 31.5 og 2. Opgave 32.1 og 32.5.

53 S L U T


Download ppt "Grafalgoritmer II."

Lignende præsentationer


Annoncer fra Google