Datastrukturer och algoritmer En kvart för lite!! Borde hunnit med graftraverseringar! Föreläsning 7 och 8 © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Innehåll Reflektioner från OU1-rättningen. Relationer (Läses på egen hand) Prioritetsköer Grafer och grafalgoritmer Kommer att fortsätta in på nästa föreläsning Kapitel (16), 14.5-8 och 17 i kursboken © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Prioritetskö Modell: Patienterna på en akutmottagning, man kommer in i en viss tidsordning men behandlas utifrån en annan ordning. Organisation: En mängd vars grundmängd är linjärt ordnad av en prioritetsordning. Avläsningar och borttagningar görs endast på de element som har högst prioritet. Andra mängdoperationer är inte aktuella © Anders Broberg, Lena Kallin Westin, 2007
Specifikation av prioritetskö Gränsytan Pqueue(val, R): Empty () Pqueue(val, R) Insert (v:val, p:Pqueue(val, R)) Pqueue(val, R) Isempty (p:Pqueue(val, R)) Bool Inspect-first(p:Pqueue(val, R)) val Delete-first (p:Pqueue(val, R)) Pqueue(val, R) R är relationen för prioritetsordningen. Ibland slås de två sista metoderna ihop. Förutsätter statisk prioritet. Placera in elementet på rätt plats från början. Dynamisk prioritet kräver en update-metod. Inte lika effektiva implementationer © Anders Broberg, Lena Kallin Westin, 2007
Specifikation av prioritetskö Prioritetskön kan ta element (val) som består av ett värde och en prioritet. Gränsytan kan varieras på flera sätt update högsta/minsta prioritetsvärdet i kön © Anders Broberg, Lena Kallin Westin, 2007
Stack och kö är specialfall Om R är den totala relationen, dvs gäller för alla par av värden blir prioritetskön en stack. Sista elementet som stoppas in hamnar alltid först. Om R är den tomma relationen, dvs inte gäller för några par av värden, blir det en kö. Sista elementet som stoppas in hamnar alltid sist. Om R är en strikt partiell ordning, som ”>”, kommer lika element behandlas som en kö. Om R är icke-strikt, som ”≥” behandlas lika element som en stack. © Anders Broberg, Lena Kallin Westin, 2007
Konstruktioner av Prioritetskö Mängd, Lexikon eller Heap Men de har vi inte stött på än… Lista, ej sorterad Insert O(1), Delete-first O(n) Lista, sorterad Insert O(n), Delete-first O(1) © Anders Broberg, Lena Kallin Westin, 2007 Rita och visa!
© Anders Broberg, Lena Kallin Westin, 2007 Tillämpningar Operativsystem som fördelar jobb mellan olika processer Enkelt sätt att sortera något. Stoppa in allt i en prioritetskö och plocka ut det igen. Hjälpmedel vid traversering av graf Jmfr på kommande föreläsningar att stack och kö används vid traversering av träd. © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Graf Bild från sidan 337 i Janlert L-E., Wiberg T., Datatyper och algoritmer, Studentlitteratur, 2000 Modell: Vägkarta med enkelriktade gator utritade. Tillämpningar Signaturdiagrammen Elektroniska kretsar Nätverk (gator, flygrutter, kommunikation) Neurala nätverk © Anders Broberg, Lena Kallin Westin, 2007
Mängdorienterad specifikation (vanlig inom matematiken) En graf G = (V, E) består av V : en mängd av noder (vertices) E : en mängd av bågar (edges) som binder samman noderna i V. En båge e = (u, v) är ett par av noder. © Anders Broberg, Lena Kallin Westin, 2007 a b V = {a, b, c, d, e} E = {(a,b), (a,c), a,d), (b,e), (c,d), (c,e), (d,e)} c d e
Navigeringsorienterad specifikation En graf är en mängd noder. Till varje nod associeras en grannskapsmängd av noder som kallas grannar. Alla noder tillhör samma typ Alla ordnade par av en godtycklig nod och en av noderna i dess grannskapsmängd utgör en båge. Specifikationen bättre för algoritmer Mer effektiva navigeringsoperationer. © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Oriktade grafer Bågen är en mängd av två noder. Noderna är grannar till varandra. Gradtalet = Antalet bågar till grannar (eller sig själv) © Anders Broberg, Lena Kallin Westin, 2007 a b c d e
© Anders Broberg, Lena Kallin Westin, 2007 Riktade grafer Bågen är ordnade par av noder. Gradtalet indelas i Ingradtalet = antalet bågar som går till noden Utgradtalet = antalet bågar som startar i noden och går till en annan nod. © Anders Broberg, Lena Kallin Westin, 2007 a b c d e
Bokens informella specifikation: Empty – konstruerar en tom graf utan noder och bågar Insert-node(v, g) – sätter in noden v i grafen g Insert-edge(e, g) – sätter in en båge e i grafen g. Det förutsätts att noderna finns i grafen Isempty(g) – testar om grafen g är tom, dvs utan noder Has-no-edges(g) – testar om grafen g saknar bågar Choose-node(g) – väljer ut en nod ur grafen g Neighbours(v, g) – mängden av alla grannar till v i grafen g Delete-node(v, g) – tar bort noden v ur grafen g, förutsatt att v inte ingår i någon båge Delete-edge(e, g) – tar bort bågen e ur grafen g Visa OH-bilderna från Goodrich!
© Anders Broberg, Lena Kallin Westin, 2007 Terminologi a b c d e Väg/stig (path): Sekvens av noder v1, v2, …, vn så att vi och vi+1 är grannar. Enkel väg (simple path): Inga noder förekommer två gånger i vägen. Cykel (cycle): Enkel väg där den sista noden i sekvensen är densamma som den första. Dvs första/sista noden är den enda som får finnas två gånger. En oriktad graf utan cykler är ett träd. © Anders Broberg, Lena Kallin Westin, 2007 Oriktad graf utan cykler =träd!
© Anders Broberg, Lena Kallin Westin, 2007 Terminologi Sammanhängande (connected) graf Varje nod har en väg till varje annan nod. Delgraf (subgraf) en delmängd av noderna och kanterna som formar en graf. Sammanhängande komponenter En sammanhängande subgraf © Anders Broberg, Lena Kallin Westin, 2007 a b c d e a b c d e
Connectivity (nåbarhet) Låt n = antalet noder och m = antalet bågar. En komplett graf (complete graph) får man när alla noder är grannar till alla andra. I en komplett oriktad graf är m = n(n-1)/2 För ett träd gäller m = n-1 Om grafen är sammanhängande så är m ≥ n-1 © Anders Broberg, Lena Kallin Westin, 2007 Alla noder har n-1 kanter dvs n*(n-1) men då räknar vi kanterna dubbelt så därför / 2 m=5, n =6 a b d c m=6, n =4 a b c d e m=3, n =5
© Anders Broberg, Lena Kallin Westin, 2007 Digraph och DAGs DiGraph = Directed graph dvs riktad graf kan vara sammanhängande kan ha sammanhängande komponenter DAG = Directed Acyclic Graf dvs, en riktad graf utan cykler a b c d e © Anders Broberg, Lena Kallin Westin, 2007 Bilder på starkt kopplade riktade grafer…. a b c d e
© Anders Broberg, Lena Kallin Westin, 2007 Mer grafer… Viktad graf En graf där bågarna har vikter Multigraf Tillåtet med flera bågar mellan två noder. Dessa bågar har då oftast olika egenskaper som måste lagras. Ordnad graf har inbördes ordning mellan grannarna till en nod. © Anders Broberg, Lena Kallin Westin, 2007
Konstruktion av grafer b c d e Förbindelsematris Bågarna representeras av ettor i en matris. Rad 1 visar vilka bågar man kan nå från a. Kolumn 3 visar från vilka noder det kommer bågar till c. + Enkel att implementera och passar när man har siffror på noder och bågar. Matrisen kan bli stor och gles och kräva specialtrick. 1 2 3 4 5
Konstruktion av grafer c a b Graf som fält av lista. Listan är grannskapslistan. Man utgår att det finns minst en båge från varje nod (Fält) men inte att går en båge från varje nod till varje annan nod (därför Lista). + Inte lika utrymmeskrävande som en gles matris. Utrymmet = O(n+m) - Fixt antal noder d e a b c d e c d e c © Anders Broberg, Lena Kallin Westin, 2007 e Kan ju också göra det som en lista av listor b c
© Anders Broberg, Lena Kallin Westin, 2007 Grafalgoritmer Traversering Bredden-först och djupet-först Konstruera ett (minsta) uppspännande träd Finna vägarna från en nod till alla andra noder Kortaste vägen mellan två noder Finna maximala flödet Finna det maximala flödet mellan två noder © Anders Broberg, Lena Kallin Westin, 2007
Djupet-först-traversering Besök utgångsnoden och sedan dess grannar djupet-först rekursivt. Undersöka en labyrint genom att markera de vägar man gått med färg. Cykler medför risk för oändlig traversering Håll reda på om noden är besökt eller ej. Om redan besökt görs inget rekursivt anrop. Endast de noder man kan nå från utgångsnoden kommer att besökas. Problem med grafer som ej är sammanhängande. © Anders Broberg, Lena Kallin Westin, 2007
Djupet-först-algoritm: Algoritm depthFirst(Node n, Graph g) input: A node n in a graph g to be traversed visited(n, g) // Marks the node as visited neighbourSet neighbours(n, g); for each neighbour in neighbourSet do if not isVisited(neighbour) depthFirst(neighbour, g) © Anders Broberg, Lena Kallin Westin, 2007 djupet_först.ppt
Bredden-först-algoritm Man undersöker först noden, sedan dess grannar, grannarnas grannar osv. Risk för oändlig körning om man inte använder en markör för att noden besökts. Endast noder till vilka det finns en väg från utgångsnoden kommer att besökas. En kö hjälper oss hålla reda på grannarna. © Anders Broberg, Lena Kallin Westin, 2007
Bredden-först-algoritm: Algoritm breadthFirst(Node n, Graph g) input: A node n in a graph g to be traversed Queue q empty(); visited(n, g) // Marks the node as visited q enqueue(n, q); while not isempty(q) do newNode front(q) q dequeue(q); neighbourSet neighbours(newNode, g); for each neighbour in neighbourSet do if not isVisited(neighbour) visited(neighbour, g); q enqueue(neighbour, q); © Anders Broberg, Lena Kallin Westin, 2007 bredden_först.ppt
© Anders Broberg, Lena Kallin Westin, 2007 Uppspännande träd Både bredden-först och djupet-först-traverseringarna ger oss uppspännande träd. Om vi sparat undan informationen... Måste utöka grafspecifikationen Är det minimalt? Den totala längden i trädet ska vara minimalt. Om varje kant har samma vikt är trädet minimalt uppspännande för bredden-först traversering. Om man lägger till kravet att varje nod ska ha så kort väg som möjligt till roten. © Anders Broberg, Lena Kallin Westin, 2007
Uppspännande träd Skapat med djupet-först Ej minimalt B C Skapat med djupet-först Ej minimalt E F G A B C I J K E F G Skapat med bredden-först Minimalt Antalet färgade kanter = 8 i båda fallen. I J K
Uppspännande träd Jämför vägen A till F! Skapat med djupet-först Ej minimalt Skapat med bredden-först Minimalt A A E E F B I I C J G J G K C K Uppspännande träd Jämför vägen A till F! B F
© Anders Broberg, Lena Kallin Westin, 2007 Tidskomplexitet För bredden-först och djupet-först gäller: n = antalet noder, m = antalet bågar Varje nod besöks exakt en gång O(n) För varje nod följer man bågarna ut från noden för att hitta grannarna. Bör ha O(grad(v)), värsta fallet O(n). Används mängdorienterad spec. får man O(m) Grannmängden behöver evalueras en gång för varje nod blir komplexiteten O( grad(v)) =O(m) Varje båge tillhör två grannskap Totalt O(n) + O(m) © Anders Broberg, Lena Kallin Westin, 2007
Kortaste-vägen-algoritm vid lika vikt Graf med lika vikter på alla bågar Använd en variant av bredden-först traversering för att beräkna kostnaden för den kortaste vägen från en nod till de andra. Byt från vanlig kö till prioritetskö. Lägg till metoder för att lagra avståndet från startnod till aktuell nod i noderna. © Anders Broberg, Lena Kallin Westin, 2007
Kortaste-vägen-algoritm vid lika vikt Algoritm breadthFirst(Node n, Graph g) input: A node n in a graph g to be traversed PrioQueue q empty(); visited(n, g) // Marks the node as visited setDist(n, 0) q insert(n, q); while not isempty(q) do newNode inspectFirst(q) q deleteFirst(q); neighbourSet neighbours(newNode, g); for each neighbour in neighbourSet do if not isVisited(neighbour) visited(neighbour, g); setDist(neighbour, getDist(newNode)+1) q insert(neighbour, q); © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 1 2 A B C E F G I J K 1 1 3 A © Anders Broberg, Lena Kallin Westin, 2007 2 3 4 E F B I C Om alla bågar har vikt 1 J G K
© Anders Broberg, Lena Kallin Westin, 2007 Uppspännande träd Hur hanterar man grafer med vikter? Uppspännande träd med minsta totala längd. Det är alltså inte en kortaste-vägen algoritm! För navigeringsorienterad specifikation Prims algoritm För mängdorienterad specifikation Kruskals algoritm © Anders Broberg, Lena Kallin Westin, 2007 A R B F C D E G 4 6 8 5 3
© Anders Broberg, Lena Kallin Westin, 2007 Prims algoritm Går ut på att bygga upp ett allt större träd som till slut spänner upp grafen eller en sammanhängande komponent av den. I varje steg väljs en båge med minimal vikt. Lika vikter måste behandlas konsekvent. Regeln styr hur det färdiga trädet ser ut. © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Prims algoritm: Välj en nod vilken som helst och markera den som öppen. Låt den bli rot. Markera den som stängd. För var och en av (de icke-stängda) grannarna: Markera den som öppen (om den inte är det). Stoppa in den aktuella noden, grannen och vikten i en prioritetskö. Är vikterna lika ska det nya elementet läggas in först i kön. (Dvs relationen är ) Ta fram ett element ur prioritetskön och bilda ett nytt delträd genom att lägga in den båge som finns i elementet i trädet. OBS! Lägg endast in bågen om slutnoden inte är stängd! Låt slutnoden bli den nya aktuella noden, stäng den och gå till 3. © Anders Broberg, Lena Kallin Westin, 2007 (n, neighbour, w) borde skrivas som en egen typ men slarvar!! prim.ppt
Resultat av Prims algoritm: B F C D E G 4 6 8 5 3 A R B F C D E G 4 6 8 5 3 A R B F C D E G 4 6 8 5 3 Start Slut med Slut med <
Prims algoritm - komplexitet Man gör en traversering av grafen, dvs O(m) + O(n). Sen tillkommer köoperationer För varje båge sätter man in ett element i kön, inspekterar det och tar ut det. Detta blir O(m*Kökostnad) Kökostnad: Lista O(m), Heap (partiellt sorterat binärt träd) ger O(log m). Totalt: O(n) + O(m2) eller O(n) + O(m log m) beroende på implementation av prioritetskön. © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Kruskals algoritm Väljer bågar allt eftersom men formar inte delträd under konstruktionen. Ingen traversering utan arbetar på ett annat sätt med bågarna. Färglägg bågarna för att hålla reda på vilken delgraf de tillhör. © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Kruskals algoritm Skapa en prioritetskö av alla bågarna utifrån vikterna på dessa. Den första bågen plockas fram och bildar den första delgrafen. Noderna färgläggs. Upprepa tills kön är tom: Ta fram en ny båge. Om ingen av noderna är färgade Färglägg med ny färg och bilda ny delgraf. Om endast en nod är färgad Ingen risk för cykel utöka grafen och färglägg. Om båda noderna är färgade med olika färg Välj en av färgerna och färga om den nya gemensamma grafen. Om båda noderna har samma färg Ignorera bågen, den skapar en cykel © Anders Broberg, Lena Kallin Westin, 2007 kruskal.ppt
Kruskals algoritm - komplexitet Först byggs en prioritetskö från bågmängden Komplexitet beror på implementationen av bågmängden och prioritetskön… Varje båge traverseras en gång. Resten kan delas in i fyra fall: Tre fall med komplexitet O(1) där bågen kan läggas till utan problem. Ett fall där en delgraf måste färgas om. Komplexitet O(n). © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Finna vägen till en nod Bredden-först traversering ger oss vägarna från en nod till alla andra. Om vi sparar undan vägen… Är det den kortaste? Ja, om alla vikter lika! Annars då? Vi kommer titta på två algoritmer: Floyds shortest path O(N3) Dijkstras shortest path © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Floyds shortest path Representera grafen med hjälp av en matris. A B C D E F G R 8 6 4 3 5 A R B F C D E G 4 6 8 5 3 © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Floyds shortest path Algoritm floyd(Graph g) input: A graph g to find shortest path in // Get matrix representation A(:,:,0) getMatrix(g) N getNoOfNodes(g) for k=0 to N-1 for i=0 to N-1 for j=0 to N-1 A(i,j,k+1) = min(A(i,j,k), A(i,k,k)+ A(k,j,k)) © Anders Broberg, Lena Kallin Westin, 2007 A(:,:,N) innehåller kortaste avstånden men hur få tag på vägen? Spara på samma gång en föregångar- matris. Det kommer också kosta O(N3) så den ökar inte komplexiteten.
© Anders Broberg, Lena Kallin Westin, 2007 Uppdaterad Floyd Algoritm floyd(Graph g) input: A graph g to find shortest path in // Get matrix representation A(:,:,0) getMatrix(g) N getNoOfNodes(g) for i = 0 to N-1 for j = 0 to N-1 if (i==j or A(i,j,0)==inf) Path(i,j,0) = -1 else Path(i,j,0) = i for k=0 to N-1 for i=0 to N-1 for j=0 to N-1 A(i,j,k+1) = min(A(i,j,k), A(i,k,k)+A(k,j,k)) if (A(i,j,k) A(i,k,k)+A(k,j,k)) Path(i,j,k+1) = Path(i,j,k) else Path(i,j,k+1) = Path(k,j,k) © Anders Broberg, Lena Kallin Westin, 2007
Vi har hittat en kortare väg mellan A och C. Vilken är den? B F C D E G 4 6 8 5 3 k0 A B C D E F G R 8 6 4 3 5 k9 A B C D E F G R 10 7 12 6 4 11 8 3 16 5 15 9 Vi har hittat en kortare väg mellan A och C. Vilken är den? Vilken är vägen mellan R och G?
A B C D E F G R - Låt oss leta i vår föregångarmatris. (För enkelhetens skull har jag kodat om siffrorna till motsvarande noder på OH-bilden.) R 6 4 B 8 C 5 A 3 D 4 3 6 4 F E G 6 Man måste leta ”baklänges”. Om vi vill hitta vägen mellan A och C gör man så här: Titta på raden för A. Leta reda på kolumnen för C. Där ser vi F. Sedan tittar vi i kolumnen för F där ser vi A. Vägen är alltså A-F-C. På samma sätt ser vi att kortaste vägen mellan R och G är R-A-F-C-G (med kostnad 15).
© Anders Broberg, Lena Kallin Westin, 2007 Dijkstras algoritm Kortaste vägen från en nod n till alla andra Ett exempel på en ”Girig” algoritm Ta det bästa steget i varje varv I detta fall leder det också till ett globalt min Fungerar bara på grafer med positiva vikter. Låt varje nod ha följande attribut Visited – sann när vi hittat en väg till den Distance – längden på den kortaste vägen fram till noden Parent – Referens till föregångaren på vägen © Anders Broberg, Lena Kallin Westin, 2007 Ett exempel på "giriga (greedy) algoritmer": i varje steg plocka ut den "bästa" noden. Det leder i detta problem också till den globalt bästa vägen.
Dijkstras algoritm Algoritm dijkstra(Node n, Graph g) input: A graph g to find shortest path starting from node n n.visited true; n.distance 0; n.parent null; Pqueue q empty(); q insert(n,q); while not isempty(q) v inspect-first(q); q delete-first(q); d v.distance; neighbourSet neighbours(v, g); for each w in neighbourSet do newDist d + getWeight(v,w); if not isVisited(w) w.visited true; w.distance newDist; w.parent v; q insert(w,q); else if newDist < w.distance w.parent v; q update(w,q) Påminn om att man kan lägga in i tabell…
Dijkstras algoritm - komplexitet Vi sätter in varje nod i kön en gång. Totalt n*O(insert) Vi tar ut varje nod ur kön en gång. Totalt n*O(delete-first) Vi kan behöva uppdatera element i kön. Maximalt m gånger, m*O(update) Osorterad lista n*O(1)+n*O(n) + m*O(1) = O(n2) +O(m) Om kön är implementerad som Heap n*O(log n)+n*O(log n) + m*O(log n) = O((n+m)log n) © Anders Broberg, Lena Kallin Westin, 2007 Om smart implementation…
© Anders Broberg, Lena Kallin Westin, 2007 Floyd vs. Dijkstra Floyd O(n3) hittar den kortaste vägen mellan alla noder. Dijkstra O((n+m) log n) med heap, hittar kortaste vägen mellan en nod och alla andra. Måste köras N gånger för att få samma resultat som Floyd. Dvs O(n(n+m) log n). Är bättre på stora glesa grafer. © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Flödet i en graf Riktad graf med vikter cv,w, som anger flödeskapacitet över bågen (v,w). Kapaciteten kan t.ex. vara mängden vätska som kan flöda genom ett rör, maximala mängden trafik på en väg eller kommunikationskapaciteten i ett datornät. Grafen har två noder s (source) och t (sink) och uppgiften är att beräkna det maximala flödet mellan s och t. Genom varje båge (u,v) kan vi maximalt ha ett flöde på cu,v enheter. För varje nod v gäller att det totala inkommande flödet måste vara lika med det utgående flödet. © Anders Broberg, Lena Kallin Westin, 2007
© Anders Broberg, Lena Kallin Westin, 2007 Kapacitet och flöde Flödet är en funktion på kanterna: 0 ≤ flöde ≤ c(u, v) Flödet in till noden = flödet ut ur noden Värde/value: Det kombinerade flödet in till avloppet. © Anders Broberg, Lena Kallin Westin, 2007 s t 2 3 1 4 s t 2 3 1 4 1 2 1 2 1 1 2 1 1
Maximumflödes problem Givet ett nätverk N, hitta ett flöde med maximalt värde Ett exempel på maximalt flöde Värde = 5 s t 2 3 1 4 © Anders Broberg, Lena Kallin Westin, 2007
Förbättrande (augmenting) flöde s s 2 2 2 2 2 1 1 1 Nätverk med flödes- värde 3 1 2 2 2 2 1 2 t t Förbättrande väg (Augmenting path) s 2 2 2 2 Nu har flödesvärdet ökat till 4!! 1 2 2 2 2 t
© Anders Broberg, Lena Kallin Westin, 2007 Ökande väg Framåtriktade bågar flödet(u, v) < c(u, v) Flödet kan ökas! v u © Anders Broberg, Lena Kallin Westin, 2007 Bakåtriktade bågar flödet(u,v) > 0 Flödet kan minskas! v u
Maximala flödesteoremet + algoritm Ett flöde har maximum värde om och endast om nätverket inte har någon förbättrande väg. Ford & Fulkerson algoritmen: Initialisera nätverket med noll flöde Anropa metoden findFlow() som definieras Om det finns förbättrande vägar: Hitta en av dem Öka flödet Anropa (rekursivt) findFlow() © Anders Broberg, Lena Kallin Westin, 2007
Initiera nätverket med nollflöde. Kapaciteterna i svart ovan bågarna och flödet i grönt nedan bågarna. Skicka igenom ett enhetsflöde genom nätverket. Flödesvägen markerat med rött och de förbättrade flödesvärdena i blått.
Skicka ytterligare ett enhetsflöde genom nätverket. Skicka igenom ytterligare ett enhets- flöde genom nätverket. Notera att det finns ytterligare en förbättrande väg som går genom kanten i mitten.
Skicka ett enhetsflöde genom den förbättrande vägen Skicka ett enhetsflöde genom den förbättrande vägen. Nu finns det inga fler förbättrande vägar. Alltså… Vi har hittat detta nätverks maximala flöde!
Hur gör man mer specifikt? Hur vet man att det finns en förbättrande väg? Hur vet man vilken av de förbättrade vägarna man ska ta först? Algoritmen på sidorna 355-358 mer specifik. Noderna numreras och numren används som en fast prioritetsordning i en kö. © Anders Broberg, Lena Kallin Westin, 2007
Första vägen från s till t: (-, ) Första vägen från s till t: s märks som stängd och (-, ) (dvs inte öppnats från någon nod flödet kan förändras oändligt) Bågarna från s traverseras, noderna i andra änden markeras öppna och märks med deras maximala kapacitet och sätts in i prio-kön. q = (a, b) s 2 2 1 a b 2 2 t (-, ) s 2 2 (s, 2) 1 a b (s, 2) 2 2 t
(-, ) Första noden tas från kön (a) och markeras stängd. Dess bågar undersöks i tur och ordning. Bågen (a,s) leder till stängd nod och (a, b) leder till öppen nod - inget händer. Bågen (a,t) leder till en ny nod t som markeras (a, 2) Nu har vi nått fram till t, traverseringen avbryts. Man följer stegen bakåt till s och markerar bågarna samtidigt som noderna avmarkeras. s 2 2 (s, 2) 1 (s, 2) a b 2 2 t (a, 2) s 2 2 2 1 a b 2 2 2 t
Andra vägen från s till t: (-, ) Andra vägen från s till t: s märks som stängd och (-, ) Bågarna från s traverseras. Eftersom vägen till a inte kan ökas mer struntar vi i den. q=(b) Första noden tas från kön (b) och markeras stängd. Dess bågar undersöks i tur och ordning. Bågen (b,s) leder till stängd nod - inget händer. Bågen (b,a) leder till en ny nod a (baklänges) som kan markeras med maximalt det nuvarande flödet, dvs (b, 0). Bågen (b,t) leder till en ny nod t som markeras (b, 2). q=(a,t) s 2 2 2 (s, 2) 1 a b 2 2 2 t (-, ) s 2 2 2 (s, 2) (b, 0) 1 a b 2 2 2 t (b, 2)
(-, ) Första noden tas från kön (a) och markeras stängd. Dess bågar undersöks i tur och ordning. Bågen (a,s) och (a, b) leder till stängda noder och (a, t) till en öppen nod - inget händer. Första noden tas från kön (t). Vi har nått t. Traversering avbryts och vi går bakåt och avmakerar allt. Om vi nu försöker börja om igen så hittar vi inget nytt eftersom både (s,a) och (s,b) utnyttjas maximalt. s 2 2 2 (s, 2) (b, 0) 1 a b 2 2 2 t (b, 2) s 2 2 2 2 1 a b 2 2 2 2 t