Kortste pad algoritmen

Vergelijkbare documenten
Grafen. Indien de uitgraad van ieder punt 1 is, dan bevat de graaf een cykel. Indien de ingraad van ieder punt 1 is, dan bevat de graaf een cykel.

TW2020 Optimalisering

Kortste Paden. Algoritmiek

TW2020 Optimalisering

Kortste Paden. Algoritmiek

Doorzoeken van grafen. Algoritmiek

Je hebt twee uur de tijd voor het oplossen van de vraagstukken. µkw uitwerkingen. 12 juni 2015

2WO12: Optimalisering in Netwerken

V = {a, b, c, d, e} Computernetwerken: de knopen zijn machines in het netwerk, de kanten zijn communicatiekanalen.

Elfde college algoritmiek. 10 mei Algoritme van Dijkstra, Gretige Algoritmen

Uitwerking tentamen Analyse van Algoritmen, 29 januari

Discrete Wiskunde, College 12. Han Hoogeveen, Utrecht University

Discrete Structuren. Piter Dykstra Sietse Achterop Opleidingsinstituut Informatica en Cognitie

Discrete Structuren. Piter Dykstra Opleidingsinstituut Informatica en Cognitie

Universiteit Utrecht Betafaculteit. Examen Discrete Wiskunde II op donderdag 6 juli 2017, uur.

Elfde college algoritmiek. 18 mei Algoritme van Dijkstra, Heap, Heapify & Heapsort

Radboud Universiteit Nijmegen

Begrenzing van het aantal iteraties in het max-flow algoritme

Een combinatorische oplossing voor vraag 10 van de LIMO 2010

Examen Datastructuren en Algoritmen II

Tiende college algoritmiek. 13/21 april Gretige Algoritmen Algoritme van Dijkstra

Tentamen Discrete Wiskunde 1 10 april 2012, 14:00 17:00 uur

Overzicht. 1. Definities. 2. Basisalgoritme. 3. Label setting methoden. 4. Label correcting methoden. 5. Ondergrenzen. 6.

2 n 1. OPGAVEN 1 Hoeveel cijfers heeft het grootste bekende Mersenne-priemgetal? Met dit getal vult men 320 krantenpagina s.

III.2 De ordening op R en ongelijkheden

Benaderingsalgoritmen

l e x e voor alle e E

Getallenleer Inleiding op codeertheorie. Cursus voor de vrije ruimte

Tiende college algoritmiek. 2 mei Gretige algoritmen, Dijkstra

Netwerkdiagram voor een project. AOA: Activities On Arrows - activiteiten op de pijlen.

Tiende college algoritmiek. 14 april Gretige algoritmen

Uitgebreide uitwerking Tentamen Complexiteit, juni 2017

Vierde college complexiteit. 26 februari Beslissingsbomen en selectie Toernooimethode Adversary argument

Grafen en BFS. Mark Lekkerkerker. 24 februari 2014

Tiende college algoritmiek. 4 mei Gretige Algoritmen Algoritme van Dijkstra

2WO12: Optimalisering in Netwerken

Tweede college algoritmiek. 12 februari Grafen en bomen

Examen Datastructuren en Algoritmen II

Hebzucht loont niet altijd

Examen Datastructuren en Algoritmen II

Discrete Wiskunde 2WC15, Lente Jan Draisma

Twaalfde college algoritmiek. 13 mei Branch & Bound Heap, Heapsort & Heapify

Onafhankelijke verzamelingen en Gewogen Oplossingen, door Donald E. Knuth, The Art of Computer Programming, Volume 4, Combinatorial Algorithms

TW2020 Optimalisering

Geldwisselprobleem van Frobenius

Automaten. Informatica, UvA. Yde Venema

Jordan normaalvorm. Hoofdstuk 7

Tweede huiswerkopdracht Lineaire algebra 1 Uitwerking en opmerkingen

Eigenschappen en Axioma s van de E 6 -meetkunde

Universiteit Utrecht Betafaculteit. Examen Discrete Wiskunde op donderdag 13 april 2017, uur.

Uitgebreide uitwerking Tentamen Complexiteit, mei 2007

Gödels theorem An Incomplete Guide to Its Use and Abuse, Hoofdstuk 3

Netwerkstroming. Algoritmiek

Radboud Universiteit Nijmegen

Heuristieken en benaderingsalgoritmen. Algoritmiek

Netwerkstroming. Algoritmiek

Discrete Structuren. Piter Dykstra Opleidingsinstituut Informatica en Cognitie

Minimum Spanning Tree

Week Hier vind je uitwerkingen van enkele opgaven uit het dictaat Grafen: Kleuren en Routeren.

Gegevens invullen in HOOFDLETTERS en LEESBAAR, aub. Belgische Olympiades in de Informatica (duur : maximum 1u15 )

Combinatorische Algoritmen: Binary Decision Diagrams, Deel III

Tiende college algoritmiek. 26 april Gretige algoritmen

Getaltheorie I. c = c 1 = 1 c (1)

Algoritmen aan het werk

Netwerkdiagram voor een project. AON: Activities On Nodes - activiteiten op knooppunten

OPLOSSINGEN VAN DE OEFENINGEN

Hoofdstuk 3. Equivalentierelaties. 3.1 Modulo Rekenen

1 Rekenen in eindige precisie

Inleiding Analyse 2009

Tiende college algoritmiek. 14 april Dynamisch Programmeren, Gretige Algoritmen, Kortste Pad met BFS

Het minimale aantal sleutels op niveau h is derhalve

We beginnen met de eigenschappen van de gehele getallen.

Greedy algoritmes. Algoritmiek

8C080 deel BioModeling en bioinformatica

De statespace van Small World Networks

Grafen deel 2 8/9. Zesde college

Twaalfde college complexiteit. 11 mei Overzicht, MST

Aanvullingen bij Hoofdstuk 8

Algoritmiek. 15 februari Grafen en bomen

Lijstkleuring van grafen

Vierde college algoritmiek. 2 maart Toestand-actie-ruimte Exhaustive Search

De volgende opgave gaat over de B-bomen van het college, waar sleutels zowel in de bladeren als ook in de interne knopen opgeslagen worden.

1 Delers 1. 3 Grootste gemene deler en kleinste gemene veelvoud 12

Examen Datastructuren en Algoritmen II

Opdracht 3: De volhardende voetbalfan

2WO12: Optimalisering in Netwerken

Opmerking vooraf: let op, de terminologie is in elk boek weer anders!

3 De stelling van Kleene

Examen Datastructuren en Algoritmen II

TW2020 Optimalisering

Kettingbreuken. 20 april K + 1 E + 1 T + 1 T + 1 I + 1 N + 1 G + 1 B + 1 R + 1 E + 1 U + 1 K + E + 1 N A + 1 P + 1 R + 1 I + 1

Discrete modellen in de toegepaste wiskunde (WISB136) Uitwerkingen proeftentamen.

Examen Datastructuren en Algoritmen II

Vijfde college complexiteit. 21 februari Selectie Toernooimethode Adversary argument

ALGORITMIEK: antwoorden werkcollege 5

ALGORITMIEK: antwoorden werkcollege 5

Vierde college complexiteit. 14 februari Beslissingsbomen

Fractale dimensie. Eline Sommereyns 6wwIi nr.9

Elfde college complexiteit. 23 april NP-volledigheid III

Toewijzingsprobleem Bachelorscriptie

Transcriptie:

Faculteit Wetenschappen Departement Wiskunde Kortste pad algoritmen Bachelorproef 2 Lukas Boelens Promotor: Prof. Philippe Cara 1 mei 2015

Inhoudsopgave 1 Inleiding 2 2 Inleide begrippen 2 3 Eindige metrische ruimten 3 4 Breadth First Search 4 5 Bellmanvergelijkingen 7 5.1 Acyclische gerichte graffen.................... 9 5.2 Toepassing: tijdstabellen..................... 12 6 Dijkstra algoritme 14 6.1 Het algoritme........................... 15 6.2 Toepassing: Treinroosters.................... 19 6.3 Bellman-Ford........................... 20 7 Floyd-Warshall algoritme 21 A Bijlage: Code 25 A.1 BFS................................ 25 A.2 Dijkstra.............................. 26 A.3 Bellman en Ford......................... 28 A.4 Floyd-Warshall.......................... 29 A.5 DijkstraAll............................ 32 1

1 Inleiding De graffentheorie kent verschille toepassingen. Een van de belangrijkste toepassingen is het voorstellen van netwerken voor verkeer of data communicatie. Daarbij is het natuurlijk belangrijk om paden in deze netwerken te bestuderen. Soms zoeken we naar het kortste of snelste pad, in andere gevallen naar het goedkoopste of veiligste pad. Deze bachelorproef zal zich richten op het bestuderen van zulke paden. Eerst worden belangrijke begrippen gedefinieerd en zullen we het verband leggen tussen netwerken en eindige metrische ruimten. Daarna zullen we kijken naar verschille algoritmen. Het eerste algoritme dient voor paden in ongewogen graffen. Daarna zullen we kijken naar gewogen graffen, waarbij de Bellmanvergelijkingen een cruciale rol spelen. Deze vergelijkingen zullen we dan gebruiken om verschille algoritmen te construeren. De belangrijkste algoritmen zijn ook werkelijk geprogrammeerd in MAT- LAB. 2 Inleide begrippen Definitie 2.1. Een graf is een koppel G = (V, E) bestaande uit een nietlege eindige verzameling V en een verzameling E van paren uit V. Een element van V noemt men een top, een element e = {a, b} uit E noemt men een boog. We zullen deze boog noteren als ab. Een gerichte graf is een graf G = (V, E) waarbij de paren van E {(a, b) a, b V } geord zijn. We kunnen dus zeggen dat elke boog een beginpunt a en een eindpunt b heeft. Definitie 2.2. Een wandeling in een graf G is een rij van toppen t 0, t 1,..., t k zodanig dat er een boog t i 1 t i E bestaat voor alle i = 1,..., k. De top t 0 heet het beginpunt en top t k heet het eindpunt. Als de bogen van deze wandeling verschill zijn, noemen we dit een pad. Als daarbovenop de toppen verschill zijn, noemen we dit een enkelvoudig pad. Definitie 2.3. Zij G = (V, E) een graf waarop een afbeelding w : E R gedefiniëerd is, die we de lengtefunctie noemen. We noemen (G, w) een netwerk of een gewogen graf. Het getal w(e) noemt men de lengte van de boog e. Natuurlijk hangt de terminologie van w(e) af van het soort graf waarover gesproken wordt. Men kan het ook hebben over gewicht, kost, duur, inhoud, kans,... 2

Definitie 2.4. Voor elke wandeling W = (e 1,..., e n ) definiëert men de lengte van W als w(w ) := w(e 1 ) + w(e 2 ) + + w(e n ). De afstand d(a, b) tussen twee toppen a en b definiëren we als het minimum van alle lengtes van de mogelijke wandelingen van a naar b. Als a = b dan is de afstand d(a, a) = 0. Natuurlijk kan het zijn dat er geen wandeling van a naar b bestaat. In dit geval definiëren we d(a, b) =. Het kan ook voorkomen dat er geen minimum te bereiken valt. Stel bijvoorbeeld dat er tussen twee toppen a en b een cyclus bestaat van negatieve lengte. In dit geval kan deze cyclus tot in het oneindige herhaald worden. Dit probleem kan opgelost worden door de definitie te beperken tot paden. De meeste netwerken zullen echter geen cycli van negatieve lengte bevatten. In dit geval is de afstand tussen twee toppen goed gedefinieerd. 3 Eindige metrische ruimten Vooraleer we naar algoritmen kijken willen we eerst aantonen dat er een verband is tussen netwerken en metrische ruimten. Beschouw een netwerk (G, w), waar G een graf is en w een strikt positieve afbeelding w : E R + 0. Merk op dat een wandeling van top a naar b die lengte d(a, b) heeft noodzakelijk een pad is. Lemma 3.1. Zij G = (V, E) een samenhange graf met een strikt positieve lengtefunctie w. Dan is (V, d) een eindige metrische ruimte, waar d gedefiniëerd is als in Definitie 2.4. Bewijs. De afbeelding d is goed gedefinieerd en positief, dus moeten alleen nog de drie voorwaarden van een metriek nagegaan worden. (M1) Stel d(a, b) = 0 en dat a b. Dan moet er dus een wandeling zijn met lengte 0. Dit kan echter niet aangezien w een strikt positieve functie is. Er moet dus gelden dat a = b. Omgekeerd, als a = b, is per definitie d(a, b) = 0. (M2) Als de wandeling W van a naar b een kortste wandeling is (met andere woorden w(w ) = d(a, b)), dan is de omgekeerde wandeling W 1 van b naar a ook de kortste wandeling van b naar a. Met andere woorden d(a, b) = d(b, a). (M3) Neem drie toppen a, b en c. Nu moeten we bewijzen dat d(a, c) d(a, b) + d(b, c). Aangezien G samenhang is, bestaan er sowieso wandelingen tussen toppen a, b en c. De kortste wandeling W a,c van a naar c is dan per definitie korter dan de wandeling die de kortste wandeling W a,b van a naar b samenstelt met de kortste wandeling W b,c van b naar c. 3

Stelling 3.2. Een eindige metrische ruimte kan voorgesteld worden als een netwerk met een strikt positieve lengtefunctie. Bewijs. Zij (V, d) een eindige metrische ruimte. Dan is de afstand nooit. Neem dan G een complete graf met verzameling V en zij de lengtefunctie w de gegeven functie d. Laat d de afstandsfunctie van (G, w) zijn zoals we ze gedefinieerd hebben in Definitie 2.4. We moeten bewijzen dat d = w = d. Zij dus W = (e 1,..., e n ) een willekeurig pad van top a naar top b. Voor n 2 volgt uit de driehoeksongelijkheid: w(w ) := w(e 1 ) + w(e 2 ) + + w(e n ) = d(e 1 ) + d(e 2 ) + + d(e n ) d(a, b), waardoor d dus een ondergrens is. Aangezien de lengte van de boog ab gelijk is aan d(a, b), hebben we ook een wandeling van a naar b van lengte d(a, b). Hieruit volgt dus dat d = d. Dit netwerk is natuurlijk niet uniek voor deze metrische ruimte. Een netwerk noemt men optimaal als de som van alle lengtes van bogen minimaal is vergeleken met alle andere mogelijke netwerken voor eenzelfde metrische ruimte. 4 Breadth First Search We zullen nu eerst een eenvoudig geval bekijken, namelijk afstanden in graffen, of meer specifiek netwerken waar de lengte van elke boog 1 is. Het volge algoritme noemt men de breadth first search. Zij hier G een graf of gerichte graf, s een willekeurige top van G en Q een queue. De bedoeling is om de afstand van s naar alle andere toppen te bepalen. Algoritme 4.1. BFS(G, s; l) 1: Q, l(s) 0; 2: Plak s aan Q; 3: while Q do 4: Verwijder de eerste top v uit Q; 5: for w G v do 6: if l(w) ongedefinieerd then 7: l(w) l(v) + 1; 8: Voeg w toe aan Q. 9: if 10: for 11: while 4

Stelling 4.2. Algoritme 4.1 heeft complexiteit O( E ). Aan het eind van het algoritme, voldoet elke top t G aan { l(t) als l(t) gedefiniëerd is, d(s, t) = anders. Bewijs. Natuurlijk wordt elke boog op z n minst twee keer onderzocht (en in het gericht geval één keer), hetgeen leidt tot een complexiteit van O( E ). Er geldt ook dat d(s, t) = als en slechts als t niet toegangelijk is vanuit s, en dus blijft l(t) ongedefinieerd door het algoritme. Zij nu t een top zodat d(s, t). Dan geldt dat d(s, t) l(t), aangezien t door het algoritme door een pad van lengte l(t) bereikt wordt. We bewijzen nu dat de gelijkheid geldt per inductie op d(s, t). Dit is triviaal voor d(s, t) = 0, want dan is s = t. Onderstel nu dat d(s, t) = n+1 en zij (s, v 1, v 2,..., v n, t) een kortste pad van s naar t. Dan is (s, v 1, v 2,..., v n ) een kortste pad van s naar v n, en dan volgt uit de inductiehypothese dat d(s, v n ) = n = l(v n ). Daaruit volgt dus dat l(v n ) < l(t), en dus komt v n in het algoritme voor t voor, zodat t zeker bereikt wordt als buur van v n in G vn. Er volgt dus l(t) n + 1 zodat l(t) = n + 1 = d(s, t). Gevolg 4.3. Zij s een top van een graf G. Dan is G samenhang als en alleen als l(t) gedefinieerd is voor elke top t aan het einde van de breadth first search. Dit gevolg is niet van toepassing voor gerichte graffen. Als we dit voor gerichte graffen willen doen moeten we kijken naar de onderligge ongerichte graf G. Voorbeeld 4.4. Laten we nu kijken naar een voorbeeld van een gerichte graf waarop we BFS toepassen. a d h s c f b e g Figuur 1: Een gerichte graf G 5

Startwaarden: l(s) = 0; Q = {s}; Iteratie 1: v = s, l(a) = l(b) = 1; Q = {a, b}; Iteratie 2: v = a, l(c) = 2; Q = {b, c}; Iteratie 3: v = b; Q = {c}; Iteratie 4: v = c, l(d) = 3; Q = {d}.; Iteratie 5: v = d, l(e) = l(f) = 4; Q = {e, f}; Iteratie 6: v = e, l(g) = 5; Q = {f, g}; Iteratie 7: v = f; Q = {g}; Iteratie 8: v = g; Q = ; In dit geval wordt h dus niet bereikt, omdat er geen bogen zijn die naar h gaan. We zullen nu zien dat we BFS kunnen gebruiken om bipartiete graffen te identificeren. Hier is een graf G = (V, E) bipartiet als er een partitie V = S T bestaat zodat de verzamelingen van bogen binnen T en S leeg zijn en dat elke boog van G een top uit S en een top uit T verbindt. Stelling 4.5. Een graf G is bipartiet als en alleen als het geen cycli van oneven lengte bevat. Bewijs. [3] Discrete Wiskunde, Stelling 113. Deze stelling geeft dus aan dat we de afstanden d(s, t) kunnen gebruiken om een geschikte partitie van de toppenverzameling van een gegeven bipartiete graf G te vinden. Deze afstanden kunnen we via BFS vinden. We moeten er natuurlijk nog voor zorgen dat het algoritme oneven cycli kan opsporen. Dit kunnen we doen met behulp van volge eigenschap: Als BFS een boog e voor de eerste keer onderzoekt, bestaat een cyclus van oneven lengte die e bevat als en alleen als e beide toppen in hetzelfde deel van de partitie zitten. Dit geeft ons dus de juiste voorwaarde om te controleren of een graf G bipartiet is of niet. Algoritme 4.6. BIPART(G, s; S, T, bip) 1: Q, l(s) = 0, bip true, S ; 2: Plak s aan Q; 3: while Q, bip = true do 4: Verwijder de eerste top v van Q; 5: for w G v do 6: if l(w) ongedefinieerd is then 7: l(w) l(v) + 1; 8: Voeg w toe aan Q 9: else 10: if d(v) = d(w) then 11: bip false 12: if 13: if 6

14: for 15: while 16: if bip = true then 17: for v V do 18: if l(v) 0 mod 2 then 19: S S {v} 20: if 21: for 22: T V \ S 23: if We kunnen BFS ook gebruiken voor het vinden van lengte van de kleinste cyclus van een graf ofwel de taille. Zoals we al gezien hebben slaagt BFS de toppen over waarvan de afstand al is berek. Maar als we BFS starten van een bepaalde top v en dan kijken wanneer v terug voorkomt in het BFS algoritme, weten we in principe wat de kleinste cyclus is die v bevat. Het is dus enkel een kwestie van het minimum te bepalen van al de v V. Concreet maken we dus een opspanne boom vanuit elke top v. Hierbij moeten we wel rekening houden met wat de ouder van elke top x is in deze boom. Als we daar geen rekening mee hielden zou het algoritme gewoon via dezelfde boog teruggaan. Algoritme 4.7. TAILLE(G; t) 1: t ; 2: for v V do 3: S, Q {v}, parent(v) NULL, l(v) 0; 4: while Q 0 do 5: Verwijder de eerste x van Q; 6: for y G x \ {parent(x)} do 7: if y / S then 8: parent(y) x; 9: l(y) l(x) + 1; 10: Voeg y toe aan Q; 11: else 12: t min{t, D(x) + D(y) + 1}. 13: if 14: for 15: while 16: for 5 Bellmanvergelijkingen Het is nu ons doel om algoritmen te vinden die deze kortste enkelvoudige paden kunnen vinden in een algemeen netwerk. Alle geke algoritmen 7

voor dit probleem vinden zelfs een kortste enkelvoudig pad van een starttop s naar elke top t die bereikbaar is van s. Een kortste enkelvoudig pad zoeken naar een bepaalde t zal het algoritme niet minder complex maken. Dit komt door het feit dat zo een algoritme alle mogelijke bogen moet doorlopen om geen mogelijke paden over te slaan. Vanaf nu beschouwen we een gerichte graf G, zonder cycli van negatieve lengte. We kunnen V beschouwen als de verzameling {1,..., n} zonder algemeenheid te verliezen. Beschouw w ij := w(ij) als E de boog ij bevat. Anders definiëren we w ij =. Beschouw u i als de afstand d(s, i), waar s de starte top is. In de meeste gevallen nemen we gewoon s = 1. Nu moet elk kortste enkelvoudig pad van s naar i een laatste boog ki bevatten. Als we deze boog verwijderen van het enkelvoudig pad krijgen we een kortste pad van s naar k. Moest dit niet zo zijn dan zouden we een korter enkelvoudig pad van s naar k kunnen verbinden met de boog ki en een korter enkelvoudig pad bekomen dan het oorspronkelijk enkelvoudig pad. De afstanden u i moeten dus aan volge vergelijkingen voldoen. Eigenschap 5.1 (Bellmanvergelijkingen). u 1 = 0 en u i = min{u k + w ki i k} voor alle i = 2,..., n. (5.1) We zullen nu tonen dat de Bellmanvergelijkingen een unieke oplossing hebben. Stelling 5.2. Als 1 een starttop is van G en als alle cycli van G strikt positieve lengte hebben, dan bevat G een opspanne boom met wortel 1 waarvoor het enkelvoudig pad vanuit 1 naar een andere top in G altijd een kortste enkelvoudig pad is. Bewijs. Kies een willekeurige top j 1. We willen een enkelvoudig pad construeren van lengte u j van 1 naar j. Eerst kiezen we een boog kj met u j = u k + w kj, en dan een boog ik met u k = u i + w ik enzovoort. Stel nu dat deze constructie een cyclus zou hebben. Neem dus de cyclus Dan geldt dat C : v 1 v 2 v m v 1. (5.2) u v1 = u vm + w vmv1 = u vm 1 + w vm 1 v m + w vmv1 =... = u v1 + w v1 v 2 + + w vmv1, waaruit dus zou volgen dat w(c) = 0. Dit is een contradictie aangezien G alleen cycli van strikt positieve lengte bevat. Onze constructie kan dus alleen stoppen aan 1, hetgeen dus een enkelvoudig pad van 1 naar j vormt. Voor elke top i op dit enkelvoudig pad, 8

is de lengte van het deel van het enkelvoudig pad tot i gelijk aan u i. Als we dit blijven doen voor de toppen die nog niet voorkomen in de reeds geconstrueerde enkelvoudige paden, krijgen we uiteindelijk een opspanne boom met wortel 1. In het bijzonder mogen we deze techniek gebruiken voor afstanden in G, hetgeen de stelling bewijst. Dit soort opspanne boom met wortel s noemen we meestal een kortste pad boom van het netwerk (G, w) als, voor elke top v, het enkelvoudig pad van s tot v in deze boom lengte d(s, v) heeft. Voorgaande stelling bewijst dus dat zo een boom bestaat op voorwaarde dat alle cycli van G positieve lengte hebben. Stelling 5.3. Als 1 een wortel is van G en als alle cycli van G strikt positieve lengte hebben, dan hebben Bellmans vergelijkingen een unieke oplossing, namelijk de afstanden u j = d(1, j). Bewijs. Zij u 1,..., u n de afstanden in G, en zij u 1,..., u n een andere oplossing van de Bellman vergelijkingen. Stel dat u j u j voor een bepaalde j. Uit de Bellman vergelijkingen volgt dat u j de lengte van een enkelvoudig pad is van 1 naar j. Aangezien u j het kortste enkelvoudig pad is van 1 naar j, volgt dus dat u j > u j. Zij kj de laatste boog in een enkelvoudig pad van lengte u j van 1 naar j. Per inductie kunnen we veronderstellen dat u k = u k. Maar hieruit volgt dan dat u j > u j = u k + w kj = u k + w kj, hetgeen een contradictie is. Hieruit volgt dus dat u j = u j. 5.1 Acyclische gerichte graffen Definitie 5.4. Een acyclische graf is een graf die geen cycli bevat. Het is dus de bedoeling om de Bellmanvergelijkingen in (5.1) op te lossen. Laten we eerst kijken naar een eenvoudig geval, namelijk waar de graf een acyclische gerichte graf is. We kunnen in dit geval namelijk bewijzen dat het graf een topologische ordening heeft. We willen hiermee zeggen dat de toppen van het graf totaal geord kunnen worden zodat als er een boog uv bestaat van u naar v, in deze ordening geldt dat u v. We definiëren eerst de ingraad van een top v als het aantal bogen dat in deze top aankomt, en de uitgraad als het aantal bogen dat in deze top vertrekt. We noteren deze respectievelijk deg + (v) en deg (v). Nu bewijzen we eerst dat voor een acylisch gerichte graf er minstens één top is met deg + (v) = 0. Lemma 5.5. Zij G een eindige acyclisch gerichte graf. Dan bevat G op z n minst één top waarin geen boog aankomt. Bewijs. Neem een willekeurige top v 0 uit G. Als deg + (v 0 ) = 0, is er niks aan te tonen. Als dit echter niet het geval is, is er een boog v 1 v 0. Als 9

deg + (v 1 ) = 0 zijn we klaar. Als dit niet het geval is, bestaat er opnieuw een boog v 2 v 1. Aangezien G acyclisch is, geldt er dat v 2 v 0. We verkrijgen dus met het doortrekken van deze procedure een rij verschille toppen v 0, v 1,..., v k,.... Aangezien G een eindig aantal toppen heeft, moet deze rij op een bepaald moment stoppen, waardoor we een top v bereiken waarin geen bogen aankomen. Hiermee kunnen we dus volge stelling bewijzen: Stelling 5.6. Elke acyclische gerichte graf heeft een topologische ordening. Bewijs. Deze stelling is ook bewezen in [3] Discrete Wiskunde, Stelling 88. Uit het vorig lemma volgt dat er een top v bestaat waarin geen bogen aankomen. Neem nu de graf H = G \ {v}. Natuurlijk is deze graf ook acylisch. Per inductie op het aantal toppen geldt er dus dat deze graf topologisch gesorteerd is. We krijgen dus de rij toppen v 2, v 3,..., v n. Dan is dus de rij v, v 2, v 3,..., v n de gevraagde topologische ordening. Volg algoritme zal ons dan een topologische ordening van het graf G geven. De bedoeling is hier om naar de ingraad van de toppen te kijken. Daarna nemen we alle toppen met ingraad 0 samen in een lijst L en beginnen we deze te doorlopen. De eerste top met ingraad 0 krijgt index 1 toegewezen, waarna we de top als het ware uit het graf halen en de ingraad van alle adjacente toppen met 1 verlagen. Daarna worden alle nieuwe toppen met ingraad 0 in L gezet en beginnen we het proces opnieuw. Dit blijven we doen tot L leeg is. Uiteindelijk kunnen we met dit algoritme nog gebruiken om te controleren of een graf acyclisch is. Als N namelijk groter dan n+1 is, krijgen we dat er bepaalde toppen in de topologische ordening verschille keren voorkomen, hetgeen wil zeggen dat er cycli bestaan. Algoritme 5.7. TOPSORT(G; topnr, acyclisch) 1: N 1, L 2: for i = 1 to n do 3: ind(i) 0 4: for 5: for i = 1 to n do 6: for j G i do 7: ind(j) = ind(j) + 1; 8: for 9: for 10: for i = 1 to n do 11: if ind(i) = 0 then 12: Voeg i toe aan L; 13: if 14: for 10

15: while L do 16: Verwijder de eerste top v van L; 17: topnr(v) N, N N + 1; 18: for w G v do 19: ind(w) ind(w) 1; 20: if ind(w) = 0 then 21: Voeg w toe aan L. 22: if 23: for 24: while 25: if N = n + 1 then 26: acyclic true 27: else 28: acyclic false 29: if Laten we nu v vervangen door zijn index topnr(v). Dan geldt voor elke boog ij dat i < j en dus kunnen we de Bellmanvergelijkingen als volgt vereenvoudigen: u 1 = 0 en u i = min{u k + w ki : k = 1,..., i 1} voor i = 2,..., n. (5.3) We zullen nu een eenvoudig algoritme zien dat de Bellmanvergelijkingen kan oplossen met complexiteit O( E + V ). We zeggen hier dat A i de achterwaartse buren verzameling is, of met andere woorden A i = {v V vi E}. Algoritme 5.8. BELLMANACYCLIC(G; l) 1: l(1) 0; 2: for i = 2 to n do 3: l(i) = min{l(v) + w(vi)}, v A i. 4: for We kunnen dit algoritme nu ook gebruiken voor het vinden van de langste paden in acyclische gerichte graffen. We moeten simpelweg de min veranderen naar max. Algoritme 5.9. ACYCLICLONGESTPATH(G; l) 1: l(1) 0; 2: for i = 2 to n do 3: l(i) = max{l(v) + w vi }, v A i. 4: for De vraag is natuurlijk of we hetzelfde kunnen doen voor graffen in het algemeen, dus ook graffen met een of meer cycli. Daar komen we echter met hetzelfde probleem dat we hadden met cycli van negatieve lengte bij kortste 11

paden. Stel dat we een cyclus van positieve lengte hebben. Dan zouden we daar inderdaad kunnen blijven doorgaan aangezien het pad dan altijd langer wordt. Dit algoritme werkt dus alleen voor acyclische graffen, of graffen die geen cycli van positieve lengte hebben. 5.2 Toepassing: tijdstabellen Algoritme 5.9 geeft ons een manier om gemakkelijk langste paden te vinden in acyclische gerichte graffen. Dit zullen dit nu gebruiken voor het oplossen van een tabel. Bij het uitvoeren van een project is het belangrijk dat de verschille taken goed op elkaar afgestemd zijn om zo weinig mogelijk tijd en geld te verliezen. In deze sectie gaan we ons bezighouden met de chronologische volgorde van de taken. Er zijn bepaalde taken die niet mogen beginnen als andere nog niet zijn afgewerkt. Het doel is om te kijken naar de kortste tijd waarin een project kan afgewerkt worden en het verwachte tijdstip waarop een taak kan beginnen. Eerst wijzen we een top i {1,..., N} toe van een gerichte graf G aan elk van de N taken van het project. We laten ij een boog van G zijn als en slechts als taak i afgewerkt moet worden voor taak j mag beginnen. De boog ij heeft lengte w ij = d i gelijk aan de tijd dat nodig is voor het afwerken van taak i. Merk op dat G acyclisch moet zijn, omdat de taken in een cyclus van G nooit gestart zouden kunnen worden. Zoals we hebben gezien in Lemma 5.5, is er op z n minst een top v waarin geen boog aankomt. Analoog volgt er ook dat er een top w is waaruit geen boog vertrekt. We introduceren een nieuwe top s en voegen bogen sv toe voor alle v waarin geen boog aankomt. Deze top stelt de start van het project voor. Analoog introduceren we een top z en voegen we bogen wz toe vanuit toppen w waaruit geen boog vertrekt. Alle nieuwe bogen sv krijgen lengte 0, alle nieuwe bogen wz krijgen lengte d w. Op deze manier krijgen we een grotere gerichte graf H met wortel s. We kunnen veronderstellen dat H topologisch gesorteerd is. Nu stellen we de vroegst mogelijke tijd dat we aan taak i kunnen beginnen voor als t i. Aangezien alle taken voor taak i afgewerkt moeten worden, krijgen we volge vergelijkingen: t s = 0 en t i = max{t k + w ki : ki E H }. (5.4) Deze vergelijkingen zijn analoog aan Bellmanvergelijkingen en beschrijven de langste paden in H. Aangezien H topologisch gesorteerd is, kunnen deze vergelijkingen gemakkelijk opgelost worden, analoog aan Algoritme 5.8. De minimale tijdsduur van het project is de lengte T = t z vab een langste pad van s naar z. Als het project daadwerkelijk eindigt op tijd T, is het laatste punt T i wanneer taak i begonnen kan worden gegeven door de vergelijkingen: T z = T en T i = min{t j w ij : ij E H }. (5.5) 12

De lengte van het langste pad van i naar z is dus T z T i. Natuurlijk krijgen we T s = 0. Het verschil m i = T i t i tussen het vroegste en laatste tijdstip waar we aan i kunnen beginnen noemen we de speling. Alle taken i die speling m i = 0 hebben, noemen we kritiek. Als deze taak niet exact start op tijdstip T i = t i, wordt het project vertraagd. Merk op dat elk langste pad van s naar z alleen maar kritieke taken bevat. We noemen deze dan ook de kritieke paden van H. In de praktijk zal H niet alle bogen ij bevatten waarvoor i moet afgewerkt worden voor j mag beginnen, maar alleen diegenen waarvoor i een rechtstreekse voorloper van j is zodat er geen tussenligge taken zijn. We zullen als voorbeeld de constructie nemen van een nieuwe fabriek die een oude fabriek vervangt. Top Taak Tijd Voorgaande taken 1 Vragen voor aanbiedingen, bestellen 25-2 De oude fabriek afbouwen 8-3 De oude fundering afbouwen 5 2 4 De nieuwe fundering plannen 9 1 5 Leveringstijd voor de nieuwe fabriek 21 1 6 De nieuwe fundering bouwen 9 3,4 7 De nieuwe fabriek installeren 6 5,6 8 Het personeel trainen 15 1 9 De elektrische aansluiting installeren 2 7 10 Proeftermijn 1 8,9 11 Aanvaarding test en viering 2 10 25 8 15 0 1 25 25 5 21 7 9 2 2 1 2 10 11 z s 0 4 9 5 6 9 8 2 3 Figuur 2: Graf van het project Nu kunnen we volgens (5.4) dus de t i s van alle toppen bepalen: t s = 0, t 1 = 0, t 2 = 0, t 3 = 8, t 4 = 25, t 5 = 25, t 6 = 34, t 7 = 46, t 8 = 25, t 9 = 48, t 10 = 50, t 11 = 51, t z = T = 53. Analoog bepalen we alle T i s en m i s volgens (5.5): 13

T z = 53, m z = 0; T 11 = 51, m 11 = 0; T 10 = 50, m 10 = 0; T 9 = 48, m 9 = 0; T 8 = 35, m 8 = 10; T 7 = 46, m 7 = 0; T 6 = 37, m 6 = 3; T 5 = 25, m 5 = 0; T 4 = 28, m 4 = 3; T 3 = 32, m 3 = 24; T 2 = 24, m 2 = 24, T 1 = 0, m 1 = 0. We krijgen dus met andere woorden het kritiek pad (s, 1, 5, 7, 9, 10, 11, z). 6 Dijkstra algoritme Veronderstel in dit hoofdstuk dat alle lengtes niet negatief zijn. Neem s V. De bedoeling van deze sectie is nu om voor alle v V twee dingen te bepalen: 1. u v 2. Een gericht enkelvoudig pad van s naar v van deze lengte als u v eindig is. Neem nu s V de starttop van V, en T een deelverzameling van V waar s al dan niet inzit. Dan definiëren we d(s, T ) = min v T u v. (6.1) Het is direct duidelijk dat als s T, geldt dat d(s, T ) = 0 = u s. Als deze afstand eindig is, dan is dit het kortste gerichte enkelvoudig pad van s naar een top in T. In dit geval zal er op z n minst een top v m+1 T bestaan waarvoor d(s, T ) = u vm+1. Het enkelvoudig pad P := s v 1 v m v m+1 is in dit geval het kortste gericht enkelvoudig pad van s naar v m+1. Dan gelden volge eigenschappen: Eigenschap 6.1. 1. s, v 1,..., v m / T, 2. P k : (s, v 1 ), (v 1, v 2 ),..., (v k 1, v k ) is het kortste direct enkelvoudig pad van s naar v k voor 1 k m. Bewijs. 1. Stel dat dit niet zo is, of met andere woorden er is een v i T met 1 i m. Maar dan is het enkelvoudig pad P i : (s, v 1 ), (v 1, v 2 ),..., (v i 1, v i ) korter dan het pad P. Dit is een contradictie. 2. Stel dat er een ander korter pad P k : (s, v 1 ), (v 1, v 2 ),..., (v k 1, v k) bestaat. Maar dan zou P : (s, v 1 ), (v 1, v 2 ),..., (v k 1, v k), (v k, v k+1 ),..., (v m, v m+1 ) ook een korter enkelvoudig pad zijn dan P. Dit is een contradictie. 14

Het volgt dus dat d(s, T ) = min{u a + w(a, v)} (6.2) waar het minimum geëvalueerd wordt over alle a / T, v T. Deze formule is de basis van het Dijkstra algoritme. We beginnen met de verzameling T = V en herleiden deze verzameling tot de lege verzameling, waarbij we bij elke iteratie de top wegwerken waarvoor de afstand minimaal is in T. Zoals eerder aangegeven, geldt dat als s T, de minimale afstand d(s, T ) gelijk is aan u s = 0. Onze eerste iteratie werkt dus s weg. Zij nu dus T 1 = T \ {s}. Nu gaan we op zoek naar d(s, T 1 ) zoals in (6.2). Stel nu dat v 1 T 1 de top is waarvoor geldt dat u v1 = min{w(s, b)} = min {u a, w(a, b)} = d(s, T 1 ). (6.3) b T 1 a/ T 1,b T 1 Dan stellen we T 2 = T 1 \ {v 1 }. We gaan nu weer op zoek naar de minimale afstand. Stel nu v 2 T 2 de top waarvoor geldt dat u v2 = min {u a, w(a, b)} = d(s, T 2 ). (6.4) a/ T 2,b T 2 Dit blijven we doen tot alle toppen van V doorlopen zijn. 6.1 Het algoritme Algoritme 6.2. DIJKSTRA(G, w, s; l). Voor het algoritme voeren we de functie l : V R + in, hetgeen we voor alle v V zullen bepalen volgens vorige methode. Deze functie zal door het algoritme voor alle v V bepaald worden. De bedoeling is dat voor alle v dan geldt dat l(v) = d(s, v). Dit zullen we na het beschrijven van het algoritme bewijzen. 1: l(s) 0, T V ; 2: for v V do 3: l(v) ; 4: for 5: while T do 6: Vind u T zodat l(u) minimaal; 7: T T \ {u}; 8: for v T G u do 9: l(v) min{l(v), l(u) + w uv }. 10: for 11: while 15

Stelling 6.3. Algoritme 6.2 bepaalt met complexiteit O( V 2 ) de afstanden van de starttop s in (G, w). Er geldt dus op het einde van het algoritme t : d(s, t) = l(t) (6.5) Bewijs. Neem t V willekeurig. Als l(t) = dan is er geen wandeling van s naar t en is de stelling duidelijk juist. Stel nu dus l(t). Dan is d(s, t) l(t) aangezien het algoritme t bereikt via een gericht enkelvoudig pad van lengte l(t) van s naar t. We moeten dus alleen nog bewijzen dat l(t) d(s, t). We zullen dit doen per inductie op de orde waarin toppen uit T verwijderd worden. De eerste top die verwijderd wordt is s. Natuurlijk geldt l(s) = 0 = d(s, s). Stel nu dat de ongelijkheid waar is voor alle toppen t die voor u verwijderd werden uit T. Zij e s = v 1 e 0 2 e v1... n vn = u (6.6) het kortste enkelvoudig pad van s naar u. In dit geval geldt dus d(s, v h ) = h w(e j ), h = 0,..., n. (6.7) j=1 Neem i de maximale index zodat v i verwijderd was van T voor u. Dan volgt per inductie i d(s, v i ) = l(v i ) = w(e j ). (6.8) Aangezien v i+1 A vi, geldt uit het algoritme dat l(v i+1 ) l(v i ) + w(e i+1 ). Maar l(v i+1 ) kan niet meer toenemen en de ongelijkheid blijft dus gelden wanneer u verwijderd wordt. Met andere woorden geldt dus j=1 l(v i+1 ) l(v i ) + w(e i+1 ) = l(v i+1 ) d(s, u). (6.9) Stel eerst v i+1 u. Uit (6.9) zou d(s, u) < l(u) dus impliceren dat l(v i+1 ) < l(u), maar dan zou v i+1 uit T verwijderd zijn voor u als we kijken naar de selectie van u in de derde stap van het algoritme. Dit is in tegenspraak met het feit dat i maximaal is. Hieruit volgt dus inderdaad dat l(u) d(s, u). Stel nu dat v i+1 = u. Dan volgt de ongelijkheid direct uit vergelijking (6.9). Hieruit kunnen we dus de correctheid van het Dijkstra algoritme vaststellen. Laten we nu naar de complexiteit kijken. Het bepalen van de variabelen in stap 1 en 2 vergt O( V ) stappen. De while loop doet volge processen in O( V ) stappen: Stap 6 zoekt het minimum van alle elementen in T, en heeft dus een complexiteit van O( V ). Stap 7 heeft een complexiteit van O( V ) om het element uit de lijst te verwijderen. Beiden dragen dus een 16

complexiteit van O( V 2 ) bij aan het algoritme. Stap 9 zorgt er voor dat het algoritme exact een keer door elke boog van G, aangezien het altijd de buren bekijkt van de top die net wordt verwijdert van T. Het algoritme heeft dus een complexiteit van O( E + V 2 ) = O( V 2 ). Voorbeeld 6.4. Neem volge gerichte graf. 7 3 14 2 16 3 12 1 1 22 4 6 4 12 10 5 Figuur 3: Een netwerk We zullen hierop het Dijksta algoritme toepassen met starttop 1. Startwaarden: d(1) = 0, d(i) = voor i = 2,... 7, T = V ; Iteratie 1: u = 1, T = {2,..., 7}, d(2) = 14, d(4) = 22, d(5) = 4; Iteratie 2: u = 5, T = {2, 3, 4, 6, 7}d(4) = 16, d(6) = 14; Iteratie 3: u = 6, T = {2, 3, 4, 7}; Iteratie 4: u = 2, T = {3, 4, 7}, d(7) = 17; Iteratie 5: u = 4, T = {3, 7}; Iteratie 6: u = 7, T = {3}; Iteratie 7: u = 3, T = ; Laten we nu teruggaan naar de complexiteit van het Dijkstra algoritme. Als we naar het bewijs van Stelling 6.3 kijken zien we dat de complexiteit deels afhangt van de manier waarop we door T gaan om het minimum te zoeken en te verwijderen. Het lijkt dan ook logisch om een toepasselijke datastructuur te zoeken, aangezien stappen 6 en 7 van het algoritme de complexiteit bepalen. Een voorbeeld hiervoor is de heap. Deze datastructuur koppelt elk element aan een getal, namelijk zijn prioriteit (Engels: priority). Conceptueel is een heap een rij elementen e 1,..., e n die geord zijn volgens de heap voorwaarde: Voor alle i > 0 : e i < e 2i en e i < e 2i+1. Figuur 4 17

1 2 3 4 5 6 7 8 9 10 11 Figuur 4: Een heap indexering van een binaire boom Operaties die hierop kunnen uitgevoerd worden zijn onder andere het toevoegen van elementen naargelang de prioriteit en het vinden en verwijderen van het element met de laagste prioriteit. De laatste operatie wordt gewoonlijk aangeduid als DELETEMIN. Een heap met n elementen kan deze operaties met complexiteit O(log(n)) doen. We plaatsen de toppen van ons graf in een heap T met d als de prioriteitsfunctie (de functie die de prioriteit bepaalt). Algoritme 6.5. DIJSTRAHEAP(G, w, s; d) 1: T {s}, d(s) 0; 2: for v V \ {s} do 3: d(v) ; 4: for 5: while T do 6: u := min T ; 7: DELETEMIN (T ); 8: for v G u do 9: if d(v) = then 10: d(v) d(u) + w uv ; 11: Voeg v toe aan T met prioriteit d(v); 12: else 13: if d(u) + w uv < d(v) then 14: Verander de prioriteit van v naar d(v) d(u) + w uv 15: if 16: if 17: for 18: while Zoals al aangegeven is kunnen alle operaties binnen de while loop in O(log V ) stappen uitgevoerd worden. Tesamen hebben we zo O( E ) + O( V ) operaties. Dit resulteert dus in een complexiteit van O( E log V ). 18

6.2 Toepassing: Treinroosters Een van de toepassingen van het Dijkstra algoritme is het vinden van optimale verbindingen in een openbaar vervoersysteem. Zo een systeem bestaat uit verschille lijnen. Als iemand zo een systeem wilt gebruiken, is het soms nodig om verschille keren van lijn te veranderen. Meestal is er ook keuze tussen verschille lijnen. De bedoeling in deze sectie is om de snelste keuze te zoeken. We zullen hier het voorbeeld van treinen nemen, waarbij treinen vertrekken en aankomen op vaste tijdstippen. We beginnen met het construeren van een gerichte graf G = (V, E) met de treinstations als toppen en spoorlijnen tussen stations als bogen. Met elke boog e associëren we een reistijd f(e). We kunnen ook parallele bogen gebruiken om aan te geven dat treinen op verschille snelheden gaan. Bogen verbinden altijd stations van een lijn waar de trein daadwerkelijk stopt. Stations waar de trein gewoon langskomt komen niet voor op deze lijn. Lijnen zijn dus paden of cycli in G. Met elke lijn L associëren we een tijdsinterval T L die de tijd voorstelt tussen twee opeenvolge treinen op dezelfde lijn. Voor elk station v op een lijn L definiëren we de tijdcyclus t L (v) dewelke aangeeft wanneer de treinen van lijn L station v verlaten. Zij nu e L : v 1 0 v1 en v n. (6.10) een lijn. Het is duidelijk dat de vertrektijd in station v i de som is van de vertrektijd in station v i 1 en de reistijd f(e i ) van v i 1 naar v i modulo T L. De waarden t L (v i ) worden dus als volgt berekent: t L (v 0 ) := s L (mod T l ); t L (v i ) := t L (v i 1 ) + f(e i ) (mod T L ) voor i = 1,..., n; (6.11) Vervolgens moeten we de wachttijden bepalen bij het overstappen naar een andere trein. Zij e = uv en e = vw bogen van respectievelijk lijnen L en L. Een trein van lijn L verlaat station v op tijden t L (v), t L (v) + T L, t L + 2T L,... Een trein van lijn L bereikt station v op tijden t L (v), t L (v) + T L, t L + 2T L,... Veronderstel nu dat L en L verschille tijdscycli hebben. De wachttijden hangen dan niet alleen af van de tijdscycli, maar ook het precieze tijdspunt modulo de kleinst gemene deler T van T L en T L. Laten we dus stellen dat alle tijdscycli gelijk zijn. De wachttijden worden dan gegeven door w(vll ) = t L (v) t L (v) (mod T ). 19

We construeren nu een gerichte graf G = (V, E ) hetgeen ons een optimale connectie zal geven tussen twee stations door het vinden van een kortste pad. Een connectie tussen twee toppen v 0 en v n is hier een pad e P : v 1 0 v1 en v n tesamen met met de specificatie van de lijn L i van boog e i voor i = 1,..., n. De reistijd voor deze connectie is f(e 1 ) + w(v L1 L 2 ) + f(e 2 ) + w(v L2 L 3 ) + + w(v Ln 1 L n ) + f(e n ). (6.12) We zullen nu G als volgt definiëren. Voor elke top v V en elke lijn L die in v stopt hebben we twee toppen (v, L) in en (v, L) out in V. Voor elke boog e = vw in een lijn L is er boog (v, L) out (w, L) in in E. Daarbovenop is er voor elke top v waar twee lijnen L en L stoppen een boog (v, L) in (v, L) out. Dan komt een gericht pad van v 0 naar v n in G overeen met een connectie tussen v 0 en v n, waarbij de informatie over welke lijnen worden gebruikt en wanneer er moet overgestapt worden, inbegrepen wordt. Om de reistijd (6.12) te bepalen, definiëren we gewichtsfunctie w op G als volgt: w ((v, L) out (w, L) in ) := f(vw); w ((v, L) in )(v, L ) out := w(v LL ). Hiermee is ons oorspronkelijk probleem opgelost door Dijkstra s algoritme toe te passen op het netwerk (G, w ). 6.3 Bellman-Ford Een ander algoritme om via Bellmanvergelijkingen kortste paden te bepalen is het Bellman-Ford algoritme. Dit algoritme is met complexiteit O( V E ) trager dan Dijkstra maar heeft wel het voordeel dat het ook graffen kan behandelen waar negatieve lengtes voorkomen, zolang het geen cyclus van negatieve lengte bevat. Algoritme 6.6. BELLFORD(G, w, s; l) 1: l(s) 0; 2: for v V \ {s} do 3: l(v) ; 4: for 5: repeat 6: for v V do 7: l (v) l(v); 8: for 9: for v V do 10: l(v) min{l (v), min{l (u) + w uv : uv E}}; 11: for 12: until l (v) = l(v). 20

7 Floyd-Warshall algoritme Soms is het niet genoeg om de afstanden te bepalen ten opzichte van een bepaalde top s in een gegeven netwerk. We willen de afstand tussen alle toppen kennen. Natuurlijk kunnen we een van de geziene algoritmen verschille keren gebruiken voor alle toppen in V. Als een algoritme dus bijvoorbeeld complexiteit O(N) heeft, volgt dus dat we voor alle v V een algoritme krijgen van complexiteit O( V N). We zullen nu een algoritme zien dat dit probleem met dezelfde complexiteit als het Dijkstra algoritme oplost, namelijk O( V 3 ). Het voordeel is wel dat het algoritme negatieve lengtes toelaat. Cycli van negatieve lengte zijn wel niet toegelaten. Zij (G, w) een netwerk die geen cylci van negatieve lengtes bevat, en stel V = 1,..., n. Stel dat w ij = als ij geen boog is in G. Dit algoritme werkt door het bepalen van de afstandsmatrix D = (d(v, w)) v,w V van het netwerk. Algoritme 7.1. FLOYD-WARSHALL(G, w; d) 1: for i = 1 to n do 2: for j = 1to n do 3: if i j then 4: d(i, j) w ij 5: else 6: d(i, j) 0 7: if 8: for 9: for 10: for k = 1 to n do 11: for i = 1 to n do 12: for j = 1 to n do 13: d(i, j) min{d(i, j), d(i, k) + d(k, j)}. 14: for 15: for 16: for Stelling 7.2. Algoritme 7.1 berekent de afstandsmatrix D voor (G, w) met complexiteit O( V 3 ). Bewijs. De complexiteit van het algoritme volgt uit de for loop van regel 10. Zij nu D 0 = (d 0 ij ) de matrix gedefinieerd in de for loop van regel 1. Zij D k = (d k ij ) de matrix gegenereerd na de k-de iteratie van regel 10. We zullen nu per inductie bewijzen dat d k ij de kortste lengte van een gericht pad van i naar j is die alleen tussenligge toppen van {1,..., k} heeft. 21

Voor k = 0 is dit duidelijk. Stel nu dat de inductiehypothese geldt voor 1 tot en met k. Neem dus het kortste pad van i naar j met tussenligge toppen uit {1,..., k}. In het geval dat d k ij d(i, k + 1) + d(k + 1, j) kunnen we gewoon stellen dat d k+1 ij = d k ij, als dk ij > d(i, k + 1) + d(k + 1, j), is het duidelijk dat we een korter pad van i naar j met tussenligge toppen van {1,..., k + 1} hebben gevonden. Aangezien we gesteld hebben dat (G, w) geen cycli van negatieve lengte bevat, geldt de bewering ook voor k = n. Voorbeeld 7.3. Neem volge gerichte graf 4 2 3 10 6 4 5 2 1 5 3 6 4 3 4 9 2 3 6 3 2 7 Figuur 5: Gerichte graf I Als we nu het FLOYD-WARSHALL uitvoeren op I, krijgen we na de eerste for loop de volge afstandsmatrix D: 0 4 5 0 6 3 10 0 4 9 3 0 6 3. 4 0 3 2 2 0 2 0 Voor de volge for loop krijgen we dan volg resultaat: 0 4 5 7 12 10 12 0 6 3 8 6 8 0 4 9 7 9 3 0 5 3 5 7 4 0 3 2 9 6 2 0 2 0 22

Zij (G, w) nu een netwerk dat geen cycli van negatieve lengte bevat. Dan is de eccentriciteit van een top v gedefinieerd als ɛ(v) = max{d(v, u) : u V } Het centrum van een netwerk is dan een top met minimale eccentriciteit. Dit centrum is gemakkelijk te bepalen met het Floyd-Warshall algoritme. Aan het eind van het algoritme is de eccentriciteit ɛ(i) gewoon weg de i- de rij van de matrix D = (d(i, j)). De centra zijn dan de toppen met minimale eccentriciteit. De extra operaties die nodig zijn om deze toppen te bepalen hebben duidelijk een kleinere complexiteit dan O( V 3 ), waaruit dus volge resultaat volgt. Stelling 7.4. Zij N een netwerk zonder cycli van negatieve lengte. Dan kunnen de centra van N bepaald worden met complexiteit O( V 3 ). We kunnen het Floyd-Warshall algoritme ook gebruiken om te kijken of een graf gerichte cycli van negatieve lengte heeft. Het is hiervoor belangrijk op te merken dat een netwerk (G, w) gerichte cycli van negatieve lengte bevat als en alleen als algoritme 7.1 een negatieve waarde voor d(i, i) uitkomt. We kunnen dus het Floyd-Warshall algoritme aanpassen voor het opsporen van negatieve cycli. Algoritme 7.5. NEGACYC(G, w; d, p, neg, K) 1: neg false, k 0; 2: for i = 1 to n do 3: for j = 1 to n do 4: if i j then 5: d(i, j) w ij ; 6: else 7: d(i, j) 0; 8: if 9: if i = j or d(i, j) = then 10: p(i, j) 0; 11: else 12: d(i, j) 0; 13: if 14: for 15: for 16: while neg =false do 17: k k + 1; 18: for i = 1 to n do 19: if d(i, k) + d(k, i) < 0 then 20: neg = true, CYCLE(G, p, k, i; K) 21: else 23

22: for j = 1 to n do 23: if d(i, k) + d(k, j) < d(i, j) then 24: d(i, j) d(i, k) + d(k, j), p(i, j) p(k, j). 25: if 26: for 27: if 28: for 29: while De operatie CYCLE beduidt hier een procedure die p gebruikt voor het construeren van een cyclus van negatieve lengte die i en k bevat. Merk op dat p(i, j) de voorganger is van j van een, op dat moment, kortste pad van i naar j. Eerst, zij v o = i, dan v 1 = p(k, i), v 2 = p(k, v 1 ) totdat v a = k = p(k, v a 1 ). Ga daarna voort met v a+1 = p(i, k), v a+2 = p(i, v a+1 ) totdat v a+b = v 0 = i = p(i, v a+b 1 ). Zo krijgen we dus een cyclus (v a+b = v 0, v a+b 1,..., v 1, v 0 ) van negatieve lengte die door i en k gaat. Algoritme 7.6. CYCLE(G, p, k, i; K) v i, K {i}; repeat v p(k, v); Voeg v toe aan K; until v = k repeat v p(i, v); Voeg v toe aan K. until v = i Als er geen cycli van negatieve lengte zijn behoud de variabele neg de waarde false op het einde van algoritme 7.5. In dit geval bevat d de afstanden in (G, w) zoals in het oorspronkelijk Floyd-Warshall algoritme. De matrix (p ij ) kan dan gebruikt worden voor het vinden van een kortste pad tussen twee gegeven toppen. Dit is gelijkaardig aan de procedure CYCLE. We krijgen dus volg resultaat. Stelling 7.7. Algoritme 7.5 bepaalt met complexiteit O( V 3 ) of het gegeven netwerk (G, w) een cyclus van negatieve lengte heeft. In het geval dat dit zo is, wordt een cyclus geconstrueerd.als dit niet zo is, maakt het algoritme de afstandmatrix (d(i, j)) voor (G, w). 24

A Bijlage: Code Voor de code stellen we gewogen grafen voor als matrices. Stel dat G een gewogen graf is met n toppen. Definieer de matrix A van een gewogen graf G als de (n n)-matrix met a ij = w(ij) als de boog ij bestaat en a ij = 0 als ij niet bestaat. A.1 BFS Het eerste algoritme is de Breadth first search (sectie 4). In dit algoritme is G de matrixrepresentatie, en s de starttop. In dit geval bestaat G alleen uit 1 en en 0 en aangezien het graf in dit geval een ongewogen graf is. We bepalen hier de vector D, hetgeen al de afstanden toont vanaf de starttop s naar alle andere toppen. We beginnen met het definiëren van de vector Q. Deze lijst moet een queue simuleren. Dit doen we door een prioriteit aan elke top te geven binnen Q. Een top die nog niet aan de queue is toegevoegd, krijgt de label Inf. Een top die wel al aan de queue is toegevoegd krijgt de label gelijk aan iter. Deze waarde wordt met 1 vergroot elke keer er een nieuwe top aan Q wordt toegevoegd. Daarna voeren we een while loop uit tot Q gelijk is aan een vector met allemaal Inf. In de loop bepalen we eerst de index, de top die eerst moet doorlopen worden, of met andere woorden de top met de laagste label in Q. In de for bepalen we dan de afstanden van alle buren van v en geven we aan dat deze toppen op hun beurt moeten doorlopen worden. function [ D ] = BFS ( G, s) n=length(g); Q = Inf(1,n); Q(s) = 1; D = Inf(1,n); D(s) = 0; iter = 2; while isequal(q, Inf(1,n)) [m,index] = min (Q); Q(index) = Inf; for i = 1:n if (G(index,i) == 0) && D(i) == Inf D(i) = D(index) + 1; Q(i) = iter; iter = iter + 1; 25

Voorbeeld A.1. Zij F de gerichte graf uit met volge matrixrepresentatie: 0 1 1 0 0 1 0 0 1 1 0 1 0 0 1 0 0 0 0 1. 0 0 0 0 0 Als we nu het BFS algoritme uitvoeren op deze graf met starttop 1 krijgen we volge resultaat: >> BFS(F,1) Q = 1 Inf Inf Inf Inf D = 0 Inf Inf Inf Inf Q = Inf 2 3 Inf Inf D = 0 1 1 Inf Inf Q = Inf Inf 3 4 5 D = 0 1 1 2 2 Q = Inf Inf Inf 4 5 D = 0 1 1 2 2 Q = Inf Inf Inf Inf 5 D = 0 1 1 2 2 Q = Inf Inf Inf Inf Inf ans = 0 1 1 2 2 A.2 Dijkstra Het tweede algoritme is het Dijkstra algoritme (sectie 6). Hier is G een matrixrepresentatie van een gewogen graf en s de starttop. De vector D is hier de afstandsvector. We zeggen eerst dat de afstanden naar alle toppen oneindig zijn, behalve de afstand naar s, die 0 is. We gebruiken hier de vector T om aan te geven welke toppen nog doorlopen moeten worden. Binnen de while loop, die wordt uitgevoerd tot T een nulvector is, wordt eerst de top index bepaalt, die de kleinste afstand heeft van de toppen die nog doorlopen moeten worden. Daarna wordt aangegeven dat deze top niet meer doorlopen moet worden, en wordt de afstand van elke buur van index aangepast. function [ D ] = Dijkstra( G, s ) 26

n=length(g); D = Inf(1,n); D(s) = 0; T = ones(1,n); while isequal(t, zeros(1,n)) Minimum = Inf; index = Inf; for i = 1:n if (T(i) == 0) && (D(i) <= Minimum) Minimum = D(i); index = i; T(index) = 0; for i = 1:n if (T(i) == 0) && (G(index, i) == 0) D(i) = min(d(i), D(index) + G(index, i)); Voorbeeld A.2. Neem de graf G van Voorbeeld 6.4. Deze heeft matrixrepresentatie 0 14 0 22 4 0 0 0 0 0 0 0 0 3 0 16 0 12 0 0 0 G = 0 0 0 0 0 0 0. 0 0 0 12 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 Als we nu Dijkstra op deze graf uitvoeren met als starttop 1, krijgen we volge resultaat. >> Dijkstra(G,1) Iteratie = 1 D = 0 14 Inf 22 4 Inf Inf Iteratie = 2 D = 0 14 Inf 16 4 14 Inf Iteratie = 3 D = 0 14 Inf 16 4 14 Inf Iteratie = 4 D = 0 14 Inf 16 4 14 17 Iteratie = 5 D = 0 14 Inf 16 4 14 17 27

Iteratie = 6 D = 0 14 Inf 16 4 14 17 Iteratie = 7 D = 0 14 Inf 16 4 14 17 ans = 0 14 Inf 16 4 14 17 A.3 Bellman en Ford Voor dit algoritme gebruiken we dezelfde argumenten als het Dijkstra algoritme. We gebruiken hier een techniek van relaxatie, waarbij het resultaat van de vorige iteratie wordt vergeleken met het resultaat van de huidige iteratie, tot beiden gelijk zijn. In dit geval is D2 het resultaat van de vorige iteratie, en Min het resultaat van de huidige iteratie voor elke top i. function [ D ] = BellFord ( G, s) n=length(g); D=Inf(1,n); D(s) = 0; D2 = zeros(1,n); while isequal(d2,d) D2 = D; for i = 1:n Min = Inf; for j = 1:n if (G(j,i) == 0) && D2(j) + G(j,i) < Min Min = D2(j) + G(j,i); D(i) = min(d2(i),min); 28

Voorbeeld A.3. Neem de graf H met matrixrepresentatie 0 28 2 0 1 0 0 0 0 0 0 9 0 10 0 0 0 0 0 0 0 24 0 27 H = 0 0 0 0 5 0 8 7 0 8 0 0 0 26 0 0 0 0 0 0 0 0 8 1 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 Als we BellFord nu uitvoeren op deze matrix met starttop 1 krijgen we volg resultaat: >> BellFord(H,1) Iteratie = 1 D2 = 0 Inf Inf Inf Inf Inf Inf D = 0 14 Inf 22 4 Inf Inf Iteratie = 2 D2 = 0 14 Inf 22 4 Inf Inf D = 0 14 Inf 16 4 14 17 Iteratie = 3 D2 = 0 14 Inf 16 4 14 17 D = 0 14 Inf 16 4 14 17 ans = 0 14 Inf 16 4 14 17 A.4 Floyd-Warshall function [ D ] = Floyd (G) n=length(g); D = zeros(n); for i = 1:n for j = 1:n if (i == j) && G(i,j) == 0 G(i,j) = Inf; for i = 1:n for j = 1:n 29

if (i == j) D(i,j) = G(i,j); else D(i,j) = 0; for k = 1:n for i = 1:n for j = 1:n D(i,j) = min(d(i,j), D(i,k) + D(k,j)); Voorbeeld A.4. Neem de gerichte graf I uit Voorbeeld 7.3 met matrixrepresentatie 0 4 5 0 0 0 0 0 0 6 3 10 0 0 0 0 0 4 0 9 0 I = 0 0 3 0 6 3 0. 0 0 0 4 0 3 2 0 0 0 0 2 0 2 0 0 0 0 0 0 0 Als we hierop het FLOYD algoritme uitvoeren krijgen we volg resultaat: >> Floyd(I) iteratie = 0 D = 0 4 5 Inf Inf Inf Inf Inf 0 6 3 10 Inf Inf Inf Inf 0 4 Inf 9 Inf Inf Inf 3 0 6 3 Inf Inf Inf Inf 4 0 3 2 Inf Inf Inf Inf 2 0 2 Inf Inf Inf Inf Inf Inf 0 iteratie = 1 D = 0 4 5 Inf Inf Inf Inf Inf 0 6 3 10 Inf Inf Inf Inf 0 4 Inf 9 Inf Inf Inf 3 0 6 3 Inf Inf Inf Inf 4 0 3 2 Inf Inf Inf Inf 2 0 2 Inf Inf Inf Inf Inf Inf 0 iteratie = 2 D = 0 4 5 7 14 Inf Inf 30

Inf 0 6 3 10 Inf Inf Inf Inf 0 4 Inf 9 Inf Inf Inf 3 0 6 3 Inf Inf Inf Inf 4 0 3 2 Inf Inf Inf Inf 2 0 2 Inf Inf Inf Inf Inf Inf 0 iteratie = 3 D = 0 4 5 7 14 14 Inf Inf 0 6 3 10 15 Inf Inf Inf 0 4 Inf 9 Inf Inf Inf 3 0 6 3 Inf Inf Inf Inf 4 0 3 2 Inf Inf Inf Inf 2 0 2 Inf Inf Inf Inf Inf Inf 0 iteratie = 4 D = 0 4 5 7 13 10 Inf Inf 0 6 3 9 6 Inf Inf Inf 0 4 10 7 Inf Inf Inf 3 0 6 3 Inf Inf Inf 7 4 0 3 2 Inf Inf Inf Inf 2 0 2 Inf Inf Inf Inf Inf Inf 0 iteratie = 5 D = 0 4 5 7 13 10 15 Inf 0 6 3 9 6 11 Inf Inf 0 4 10 7 12 Inf Inf 3 0 6 3 8 Inf Inf 7 4 0 3 2 Inf Inf 9 6 2 0 2 Inf Inf Inf Inf Inf Inf 0 iteratie = 6 D = 0 4 5 7 12 10 12 Inf 0 6 3 8 6 8 Inf Inf 0 4 9 7 9 Inf Inf 3 0 5 3 5 Inf Inf 7 4 0 3 2 Inf Inf 9 6 2 0 2 Inf Inf Inf Inf Inf Inf 0 iteratie = 7 D = 0 4 5 7 12 10 12 Inf 0 6 3 8 6 8 Inf Inf 0 4 9 7 9 Inf Inf 3 0 5 3 5 31

Inf Inf 7 4 0 3 2 Inf Inf 9 6 2 0 2 Inf Inf Inf Inf Inf Inf 0 ans = 0 4 5 7 12 10 12 Inf 0 6 3 8 6 8 Inf Inf 0 4 9 7 9 Inf Inf 3 0 5 3 5 Inf Inf 7 4 0 3 2 Inf Inf 9 6 2 0 2 Inf Inf Inf Inf Inf Inf 0 A.5 DijkstraAll Het DijsktraAll algoritme is een klein algoritme op basis van het Dijkstra algoritme dat gebruikt kan worden om de afstandsmatrix van een graf te bepalen. function [D] = DijkstraAll ( G ) n=length(g); D =zeros(n); for i = 1:n D(i,1:n) = Dijkstra (G,i); In principe is het natuurlijk mogelijk om het Dijkstra algoritme te vervangen door elk ander algoritme dat de kortste afstand bepaalt. Zo kunnen we het bijvoorbeeld vervangen door BFS in het geval dat we het hebben over een ongewogen graf. Referenties [1] http://webcourse.cs.technion.ac.il/234247/winter2003-2004/ho/wcfiles/girth.pdf, Computing the girth of a graph [2] Dieter Jungnickel, Graphs, Networks and Algorithms, Springer, Second Edition, 2004 [3] P. Cara, T. Deneckere, Discrete Wiskunde, Vrije Universiteit Brussel, 2014 [4] Ralph P. Grimaldi, Discrete and Combinatorial Mathematics, Pearson, Fifth edition, 2004 32

[5] Wolfgang De Meuter, Algoritmen en Datastructuren I, Vrije Universiteit Brussel 33