Avancerad Problemlösning och Programmering i Praktiken Grafalgoritmer II High Performance Computing Center North (HPC2N)
Grafrepresentation Igår: Grafrepresentation DFS BFS Kortaste vägen MST Kortaste vägen alla par Transitiv omslutning
Grafrepresentation Idag: Eulerpromenad Topologisk sortering Bipartit matchning Flöde
Euler walk Givet en oriktad graf G=(V,E), hitta en sluten väg P så att den varje kant E återfinns i P exakt en gång. Steg 1: Lösningen finns om och endast om varje hörn har ett jämnt antal kanter
Euler walk - algoritm Skapa en sluten väg P (DFS). Ta bort alla kanter i G som ingår i P => G G består nu av en eller flera sammanhängande grafer. (Identifiera dessa med DFS) För varje del, skapa en Eulerpromenad (rekursivt), P1,P2,...,Pk Sätt ihop delarna. Traversera P. Så fort man kommer ett hörn som finns med i en av P1,P2,...,Pk, följer man den vägen istället.
Chinese postman Givet en oriktad graf G=(V,E), hitta en sluten väg P så att den varje kant E återfinns i P minst en gång. Algoritm (utan alla detaljer ): lägg till virtuella kanter mellan udda hörn. Se sidan 292 i boken.
Topologisk sortering Används till exempel vid schemaläggning. Givet en riktad graf G=(V,E) utan cykler, numrera hörnen 1 till n, så att om hörnet v har etiketten k, så kan alla hörn som kan nås från v har etikett >k
Topologisk sortering Algoritm: initiera v.ingrad för alla hörn (tex med DFS) label = 1 för alla hörn v med v.ingrad=0, lägg in dessa i kön Q så länge som Q inte är tom ta ut v ur Q v.label = label++; för alla kanter (v,w) if (!--w.ingrad), lägg in w i Q
Bipartit matchning Rätt vanligt problem. En bipartit graf är en (oriktigad) graf G=(V,E) där alla kanter går från en mängd U till en mängd W. U W=E, U V= En bipartit matchning går ut på att hitta E E så att inga par av kanter i E har några gemensamma hörn.
Bipartit matchning Används också vid schemaläggning och liknande problem. pojke flicka tex. En girig algoritm hittar inte maximum En naiv algoritm är för långsam (2 E ) Som tur var är en effektiv algoritm enkel!
Bipartit matchning Bipartit graf 1 2 3 4 5 6 A B C D E F Matchning
Bipartit matchning Matchning 1 2 3 4 5 6 A B C D E F Förbättring
Bipartit matchning Alternerande väg En alternerande väg är en väg som börjar i u U, där u inte är med i matchningen slutar i w W, där w inte är med i matchingen varannan kant är inte med i matchningen, och varannan kant är med i matchningen. Hittas genom att rikta kanterna + DFS
Bipartit matchning Rikta grafen 1 2 3 4 5 6 A B C D E F
Bipartit matchning Algoritm repetera Hitta en alternerande väg P mha DFS Om ingen väg hittas, avbryt Byt medlemskap på kanterna i P
Max-flow, min-cut Givet en graf G=(V,E), där varje kant e har en kapacitet c(e), hitta det maximala flödet från hörnet s (source, ingrad=0), till hörnet t (sink, utgrad=0) Dvs hitta ett flöde f(e) genom varje kant 0 f(e) c(e) för alla hörn v V-{s,t}, Σ u f(u,v) = Σ w f(v,w) maximera Σ w f(s,w)
Max-flow, min-cut Exempel: c(e) / f(e) 4/3 5/5 3/2 3/3 s 7/3 v 4/2 u 7/7 t 6/5 1/1 4/3 6/3 5/5 w
Max-flow, min-cut slack s v 4/2 u slack v u = c(v,u) -f(v,u) slack u v = f(v,u) man får följa en kant åt fel håll om den har ett flöde!
Max-flow, min-cut Utökande väg (augmenting path) 4/3 5/5 3/2 3/3 s 7/3 v 4/2 u 7/7 t 6/5 1/1 4/3 6/3 5/5 w
Max-flow, min-cut Algoritm repetera hitta väg P från s till t där slack h > 0 för alla kanter om väg saknas, avbryt, maximum funnet uppdatera grafen genom att öka flow med h för alla kanter i vägen P
struct stackentry { int vertex, maxflow; list<edge *> path; } while (1) { stack<struct stackentry> vertexstack; struct stackentry se; se.maxflow = MAX_INT; // se.vertex = 0; // s for (vertexstack.push(se);!vertexstack.empty(); vertexstack.pop()) { se = vertexstack.top(); if (v[se.vertex].visited) continue; else v[se.vertex].visited = true; if (se.vertex == t) break; // Väg funnen! för alla framåtkanter e if (slack(e) > 0) { se.maxflow = MIN(se.maxflow, slack(e)); se.vertex = e.next; se.path.pushback(e); vertexstack.push(se); } samma för bakåtkanterna } if (vertexstack.empty()) break; loopa igenom se.path, uppdatera med se.maxflow }
Max-flow, min-cut slack för oriktad graf v 4/2 u slack v u = c(v,u) -f(v,u) slack u v = c(v,u) + f(v,u)
Max-flow, min-cut De kanter som DFSen når, men har slack=0, utgör min-cut 4/3 5/5 3/2 3/3 s 7/5 v 4/4 u 7/7 t 6/5 1/1 4/1 6/5 5/5 w
Bipartit matchning Bipartit matchning är specialfall av flöde s t
Dagens problem En av: 563 Crimewave (tänk implicit flöde) 10307 Killing Aliens in Borg Maze Förövning: 820 Internet bandwidth