Kap 10 Graf.

Slides:



Advertisements
Liknende presentasjoner
Kap 04 Lister. Listestrukturer Listestrukturer hensiktsmessige ved såkalte flyktige tabeller (tabeller med relativt mye innsetting/sletting)
Advertisements

Kontrollstrukturer (Kapittel 3)
The Travelling Salesperson. LOG530 Distribusjonsplanlegging 2 2 Et forsyningsskip skal starte fra VestBase for å betjene 10 forskjellig installasjoner.
Matematisk Induksjon.
Kap.8 Sortering og søking sist oppdatert • Del 1 Søking - lineær søking m/u sorterte elementer - binærsøking - analyse • Del 2 Sortering - ”gamle”
Komplett avstandstabell. LOG530 Distribusjonsplanlegging 2 2 Noen ganger er det behov for en komplett avstandstabell mellom alle nodene i et nettverk.
Øvingsforelesning 9 Flytnettverk, maksimum flyt og maksimum bipartitt matching Jon Marius Venstad Redigert og forelest av Gleb Sizov.
Forelesning nr.2 INF 1411 Elektroniske systemer
Gjenfinningssystemer og verktøy II
Forside Korteste sti BFS Modifikasjon Dijkstra Eksempel Korrekthet Analyse Øving Spørsmål Dijkstras algoritme Åsmund Eldhuset asmunde *at* stud.ntnu.no.
Dijkstras algoritme Åsmund Eldhuset asmunde *at* stud.ntnu.no
Teoriøving 4 (1) Strongly connected component: ”det maksimale settet med noder slik at for alle nodepar (u,v) i settet finnes kantene u -> v og v -> u.
Øvingsforelesning 9 Flytnettverk, maksimum flyt og
Eksempel AOA (Activity On Arc)
Øvingsforelesning 3 Grafer, BFS, DFS og hashing
Kompleksitetsanalyse
Øvingsforelesning 12 Redusering av problemer,
Alg. Dat Øvingsforelesning 3 Grafer, BFS, DFS og hashing Børge Rødsjø
INF 295 Forelesning 15 - kap 9 Grafer Hans Fr. Nordhaug (Ola Bø)
P-MP modeller. LOG530 Distribusjonsplanlegging 2 2 Det skal opprettes p fasiliteter (lager) for å betjene en gitt mengde kunder. Kundenodene er også potensielle.
Lokalisering og minimum maxavstand. LOG530 Distribusjonsplanlegging 2 2 I mange situasjoner ønsker en å finne lokaliseringer som minimerer maksimalavstanden.
The Postmans Problem. LOG530 Distribusjonsplanlegging 2 2 Mista har fått i oppdrag å vedlikeholde veiene i landsdelen. Dette er et eksempel på den klassiske.
P-CP modeller. LOG530 Distribusjonsplanlegging 2 2 Det skal opprettes p fasiliteter for å betjene en gitt mengde kunder. Kundenodene er også potensielle.
Lokalisering av transformatorstasjon. LOG530 Distribusjonsplanlegging 2 2 Nistad Kraft skal levere kraft til 8 nye boligfelt, og mottakertransformatorene.
INF150 Programmering mandag 11.9
Parameteriserte kurver
Chapter 02 Wavelets - Lineær algebra
Komplekse tall Naturlige tall
Øvingsforelesning 9 - Børge Rødsjø
1 Kap 08 Kø. 2 Kø - Definisjon En kø (eng queue) er en lineær struktur hvor elementer kan innsetttes kun i den ene enden av listen, kalt bak, og fjernes.
Kap 02 Tabeller / Tabelloperasjoner. Enkeltvariable Les inn nedbørmengde for årets 12 måneder: Les n1 Les n2 … Les n12 n1 n2 n12.
Dynamisk programmering
Ch 4 INTEGRASJON Integrasjon innebærer å finne alle funksjoner F som har f derivert. Disse funksjoner kalles antiderivert av f og formelen for de er det.
INF 295 forelesning 14 - kap 8 Disjunkt mengde ADT Hans Fr. Nordhaug (Ola Bø)
INF 295 Algoritmer og datastrukturer Forelesning 9a Søketrær Hans Fr. Nordhaug (Ola Bø)
INF 295 Algoritmer og datastrukturer Forelesning 8 Trær Hans Fr. Nordhaug (Ola Bø)
INF 295 Forelesning 16 - kap 9 Minimalt spenntre og korteste vei i grafer Hans Fredrik Nordhaug (Ola Bø)
INF 295 Forelesning 17 - kap 9 Korteste vei i grafer Hans Fr. Nordhaug (Ola Bø)
INF 295 Forelesning 18 - kap 9 Aktivitetsgrafer
INF 295 Forelesning 19 - Dynamisk programmering Korteste vei alle til alle (Floyd) Hans Fr. Nordhaug (Ola Bø)
INF 295 Algoritmer og datastrukturer Forelesning 10 Invarianter og Hashing Hans Fr. Nordhaug (Ola Bø)
Dynamiske nettsider PHP Del 2 – Kontrollstrukturer.
A randomized protocol for signing contracts (extended abstract) S.Even, O. Goldreich, A.Lempel.
Hovedfagspresentasjon
Diskrete stokastiske variable
1 Kap 06 Ordnede / Sorterte lister Oppgave nr 06_02 Polynomer Klassehierarki Javadokumentasjon.
INF 4130 Eksamen 2008 Gjennomgang.
Oppgaver til kodegenerering etc. INF-5110, 2013 Oppgave 1: Vi skal se på koden generert av TA-instruksjonene til høyre i figur 9.10 i det utdelte notatet,
Magnus Haug Algoritmer og Datastrukturer
Laplace Invers transformasjon Residue
Tautologier En tautologi er et utsagn som alltid er sant, det vil si som har T i hver linje av sannhetsverditabellen.
Lokalisering og betjening av greiner. LOG530 Distribusjonsplanlegging 2 2 Mista har fått i oppdrag å vedlikeholde veiene i landsdelen. De må derfor opprette.
Sorterings- Algoritmer Algoritmer og Datastrukturer.
Boolsk Algebra og Logiske Porter
Sterke og 2-sammenhengende komponeneter, DFS
Routing Indices For P2P Systems TDT2 – Avanserte Distribuerte Systemer Lars-Erik Bjørk.
Praktisk Midtveisevaluering av kurset («femminutterslapper») i pausen. Undervisningsfri neste uke (ingen forelesninger eller grupper). NM i programmering.
Kompletthetsteoremet
Et bevis 1 Q → R P 2 P → Q P 3 P P 4 Q 3,2,MP 5 R 4,1,MP 6 P → R 3,5,CP 7 (P → Q) → (P → R) 2,6,CP 8 (Q → R) → ((P → Q) → (P → R)) 1,7,CP Vi oppsummerer.
T.Bu Heimeoppg. 3 A B Kortaste sti frå A til B har lengde 11 Kortaste postmannrute har lengde 82 (=
Sannsynlighet og kombinatorikk
UFLP modeller. LOG530 Distribusjonsplanlegging 2 2 Det skal opprettes p fasiliteter (lager) for å betjene en gitt mengde kunder. Kundenodene er også potensielle.
Lokalisering og max minimumavstand. LOG530 Distribusjonsplanlegging 2 2 Anta at nettverket angir en region hvor McBurger skal opprettes 3 konkurrerende.
Korteste vei. LOG530 Distribusjonsplanlegging 2 2 Ofte står en overfor ønsket om å finne korteste kjørerute fra et gitt utgangspunkt til et ønsket bestemmelsessted.
LOG530 Distribusjonsplanlegging
Matematikk 1 årskurs 26. oktober 2009
Sannsynlighet og kombinatorikk
INF 295 Algoritmer og datastrukturer Forelesning 23 Kompleksitet Hans Fr. Nordhaug/ Ola Bø.
5702 Geografisk analyse Nettverksanalyse. Evaluering av nettverksstruktur Nettverksdiameter Diameteren på et nettverk representerer maksimum antall.
Kap. 9 – Computer Intelligence How Information Technology Is Conquering the World: Workplace, Private Life, and Society Professor Kai A. Olsen,
Utskrift av presentasjonen:

Kap 10 Graf

Definisjon av graf En graf G er en ordnet mengde G = (V,E) hvor - V er en mengde bestående av elementer kalt punkter / noder (vertics) - E er en mengde bestående av elementer kalt kanter (edges). Hvert element e i E er gitt ved et entydig uordnet par av punkter / noder e = [u,v]

Ordnet graf Grafen kalles ordnet hvis hvert element e i E er gitt ved et ordnet par av punkter / noder e = (u,v)

Endepunkter / Naboer Anta at e = [u,v] . u og v kalles da endepunkter til e. u og v sies også å være naboer (adjacent nodes).

Grad Med graden til u deg(u) mener vi antall elementer e i E som inneholder u.

Isolert punkt u kalles for et isolert punkt hvis deg(u) = 0

Utgrad / Inngrad La G = (V,E) være en ordnet graf og la u være et element (punkt) i V. Med utgraden til u outdeg(u) mener vi antall kanter som går ut fra u. Med inngraden til u indeg(u) mener vi antall kanter som går inn til u.

Vei P av lengde n Med en vei (path) P av lengde n, Len(P) = n, mellom to punkter u og v mener vi en sekvens av n+1 punkter P = (v0 ,v1 ,v2 ,.......,vn) slik at u = v0 v = vn vi-1 og vi er naboer for i = 1,2,....,n

Lukket vei Veien P sies å være lukket hvis vn = v0.

Enkel vei Veien P sies å være enkel hvis alle vi er ulike med unntak av vn som kan være lik v0.

Syklus En syklus er en lukket enkel vei P med Len(P) >= 3. En syklus med lengde k kalles en k-syklus.

Sammenhengende graf En graf G = (V,E) kalles sammenhengende (connected) hvis det for hvert par av punkter u og v i V finnes en vei P mellom dem.

Komplett graf En graf G = (V,E) kalles komplett hvis hvert punkt u i V er nabo til et vilkårlig annet punkt v i V.

Tre En sammenhengende graf G uten sykluser kalles et tre.

Labeled graf En graf G = (V,E) kalles labeled hvis det til en eller flere kanter e i E er assosiert data.

Vektgraf En graf G = (V,E) en vektgraf hvis det til hver kant e i E er assosiert et ikke-negativt tall w(e) kalt lengden av e. I et slikt tilfelle er hver vei P i G assosiert med en vekt w(P) som er lik summen av kantlengdene langs veien i P. 2 1 7

Multiple kanter Ulike kanter e1 og e2 kalles multiple kanter hvis de forbinder de samme endepunktene e1 = [u,v] og e2 = [u,v] .

Loop En kant kalles en loop hvis den har identiske endepunkter e = [u,u] .

Multigraf Med en multigraf mener vi en graf som kan inneholde loops og/eller multiple kanter.

Rettet graf Med en rettet graf mener vi en ordnet multigraf.

Implementering av graf Ulike implementeringer av en graf: - Nabo-matrise - Vekt-matrise - Lenket liste

Nabo-matrise La G = (V,E) være en graf. La V inneholde n punkter v1, v2, v3, …, vn . Vi definerer n x n nabo-matrisen A = (aij) ved:

Nabo-matrise for uordnet graf a b c d e a 0 1 0 1 1 b 1 0 0 0 1 A = c 0 0 0 1 0 d 1 0 1 0 0 e 1 1 0 0 0 Utsagnet: Det finnes en e E slik at e = [vi,vj] er ekvivalent med utsagnet: Det finnes en e E slik at e = [vj,vi] . Herav følger at nabo-matrisen A er symmetrisk, dvs A = AT .

Nabo-matrise for ordnet graf a b c d e a 0 1 0 1 0 b 0 0 0 0 0 A = c 0 0 0 1 0 d 0 0 0 0 0 e 1 1 0 0 0 Denne nabo-matrisen er ikke symmetrisk .

Beregning av antall veier av gitt lengde Teorem: La A = (aij) være nabo-matrisen til grafen G. La AK = (a(K)ij) (a(K)ij) vil da angi antall veier av lengde K mellom punktene i og j. Bevis: Teoremet er opplagt sant for K = 1. Anta at påstanden er sanne for K = R-1. Vi skal vise at da er påstanden sann for K = R. Vi har: Elementet a(R)ij i matrisen A fremkommer ved følgende: a(R-1)ik angir antall veier av lengde R-1 mellom i og k akj angir antall veier av lengde 1 mellom punktene k og j. Produktet vil da angi antall veier av lengde R som går fra i til j via k. Ved å summere dette produktet over alle punkter k, vil vi få totalt antall veier av lengde R mellom i og j.

Beregning av antall veier av gitt lengde Graf Nabo-matrise a b c d a 0 1 1 1 A = b 0 0 1 0 c 0 0 0 0 d 0 0 1 0 0 1 1 1 0 1 1 1 0 0 2 0 A = 0 0 1 0 0 0 1 0 = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 Det går 2 veier med lengde 2 mellom punktene a og c. 2

Beregning av antall veier mellom to punkter AK angir antall veier av lengde K mellom to punkter Br = A + A2 + A3 + … + Ar angir antall veier av lengde r eller mindre mellom to punkter Bn angir antall veier mellom to punkter (n = antall punkter)

Vei-matrise En vei-matrise P = (pij) defineres ved følgende: Herav får vi ( Bn = (bij) ):

Antall veier av gitt lengde - Algoritme antVei (A,n,p1,p2,lengde) /* Finner antall veier med gitt lengde mellom to punkter. */ /* A : Nabo-matrisen */ /* n : Dimensjon til nabo-matrisen */ /* p1 : Punkt nr 1 */ /* p2 : Punkt nr 2 */ /* lengde : Gitt veilengde */ /* ant : Returnerer med antall veier med gitt lengde */ /* mellom punktene p1 og p2 */ power(A,n,lengde,kMat) // beregner AK return kMat(p1,p2)

Vei-eksistens - Algoritme 1 Vei_Eksistens (A,n,p1,p2,eksist) /* Finner ut hvorvidt det eksisterer en vei mellom to gitt punkter. */ /* A : Nabo-matrisen */ /* n : Dimensjon til nabo-matrisen */ /* p1 : Punkt nr 1 */ /* p2 : Punkt nr 2 */ eksist := False IF A(p1,p2) != 0 THEN eksist := True ELSE k := 2 WHILE (k <= n) AND (NOT eksist) DO power(A,n,k,kMat) IF kMat(p1,p2) != 0 THEN k := k + 1 ENDIF ENDWHILE Return eksist

Vei-eksistens - Warsalls algoritme Vi definerer en sekvens av boolske n * n matriser Pk (inneholder 0 eller 1) ved: Warsall oppdaget følgende:

Vei-eksistens - Algoritme 2 vei_Matrise_P (A,n,P) /* Bestemmelse av veimatrisen P */ /* A : Nabo-matrisen */ /* n : Dimensjon til A og P */ /* P : Vei-matrisen */ FOR i := 1 TO n DO // initiering av P P = A FOR j := 1 TO n DO P[i,j] := A[i,j] ENDFOR FOR k := 1 TO n DO FOR i := 1 TO n DO P[i,j] := P[i,j] v (P[i,k] ^ P[k,j]) // oppdatering av P

Gjennomløping av en graf Dybde først gjennomløp Bredde først gjennomløp Dybde først gjennomløp kan programmeres rekursivt. Der hvor rekursiv programmering ikke benyttes, gjøres bruk av følgende: - Stakk ved dybde først gjennomløp - Kø ved bredde først gjennomløp Ved slikt gjennomløp kan vi assosiere tre ulike status-tilstander til hvert punkt i grafen: - Status = 1 : Klar status. Initieringsstatus til et punkt. - Status = 2 : Vente status. Punktet befinner seg i en stakk/kø og venter på å bli prosessert. - Status = 3 : Ferdig status. Punktet er prosessert.

Dybde først gjennomløp - Velg et startpunkt A. - Besøk en nabo til A. - Besøk naboene til naboene til A osv. Dybde_Traversal Initialiser alle punktene (status = 1) Push valgt startpunkt A til stakken og sett status(A) = 2 REPEAT Pop punktet N fra stakken Prossesser N og sett status(N) = 3 Push alle naboene (som har status = 1) til N til stakken og sett status = 2 for alle disse UNTIL stakken er tom

Dybde først gjennomløp - Rekursjon dybde_Traversal (A,n,visit) sokFra(k) visit[k] := True // søking med utgangspunkt i punktet k FOR j := 1 TO n DO IF (NOT Visit[j]) AND (A[k,j] <> NULL THEN sokFra(j) ENDIF ENDFOR FOR i := 1 TO n DO // hoved-del visit[i] := False FOR i := 1 TO n DO IF NOT visit[i] THEN sokFra(i)

Bredde først gjennomløping - Velg et startpunkt A. - Besøk alle naboene til A. - Besøk alle naboene til naboene til A osv. Bredde_Traversal Initialiser alle punktene (Status = 1) Adder valgt startpunkt A til køen og sett Status[A] = 2 REPEAT Fjern punktet N i køen. Prosesser N og sett Status[N] = 3 Adder til køen alle naboene (med Status = 1) til N og sett Status = 2 for alle disse UNTIL køen er tom

Vekt-graf Vi skal se nærmere på en vekt-graf, dvs en graf hvor hver kant er tilordnet et ikke-negativt tall. En slik graf kalles også for et nettverk.

Vekt-matrise La G være en vekt-graf med n noder. La w(e) være vekten tilordnet kanten e. På samme måte som vi tidligere har laget en nabo-matrise, lager vi nå en såkalt vekt-matrise W gitt ved:

Vekt-graf med tilhørende vekt-matrise 1 2 3 4 5 1 0 7 9 3 2 W = 2 7 0 4 6 0 3 9 4 0 8 0 4 3 6 8 0 4 5 2 0 0 4 0

Minimalisering ved gjennomløping av en graf Vi skal nå forsøke å besvare følgende to spørsmål: 1. Hvordan skal vi ut fra et eksisterende nettverk hvor det finnes en vei mellom alle punktene, konstruere et nytt nettverk slik at det fremdeles finnes en vei mellom alle punktene, men nå slik at den totale summen av kantene blir mint mulig? 2. Hvordan skal vi finne den korteste veien mellom to gitte punkter?

Minimum utspent tre - Alle punktene skal være med i treet - Den totale kant-vekten er minimalisert min_Utspent_Tre Inkluder (velg) et vilkårlig punkt REPEAT FOR alle punkter NOT inkludert DO Inkluder det punktet som har en kant med minimal vekt og som samtidig er knyttet til et av punktene som allerede er inkludert Adder dette punktet og kanten til treet ENDFOR UNTIL alle punkter er inkludert

Minimum utspent tre Korteste kant fra inkludert punkt til ikke-inkludert punkt: Begynner med et vilkårlig punkt (her 1) Korteste kant fra punt 1 er kanten til punkt 5 Korteste kant er fra punkt 1 til punkt 4 Korteste kant er fra punkt 4 til punkt 2 Korteste kant er fra punkt 2 til punkt 3

Korteste vei mellom to gitte punkter Hvordan skal vi finne korteste vei mellom to gitte punkter? Vi ønsker å finne en matrise Q som er slik at qij = lengden av den korteste veien mellom vi og vj. Vi definerer en sekvens av matriser Q0, Q1, Q2, …, Qn slik at: Vi sammenligner en gitt vei mellom to punkter i og j ved å sammenligne med en annen vei ved å gå innom et annet punkt k.

Korteste vei mellom to gitte punkter Vekt-graf Vekt-matrise 7 R S T U R 7 5 0 0 W = S 7 0 0 2 T 0 3 0 0 U 4 0 1 0 5

Korteste vei mellom to gitte punkter 7 Korteste vei mellom to gitte punkter 5 7 5 u u Q0 = 7 u u 2 u 3 u u 4 u 1 u RR RS - - SR - - SU - TS - - UR - UT - 5 R S T U = 1 2 3 4 7 5 u u Q1 = 7 12 u 2 u 3 u u 4 9 1 u RR RS - - SR SRS - SU - TS - - UR URS UT - 7 5 u 7 Q2 = 7 12 u 2 10 3 u 5 4 9 1 11 RR RS - RSU SR SRS - SU TSR TS - TSU UR URS UT URS 7 5 u 7 Q3 = 7 12 u 2 10 3 u 5 4 4 1 6 RR RS - RSU SR SRS - SU TSR TS - TSU UR UTS UT UTSU 7 5 8 7 Q4 = 6 6 3 2 9 3 6 5 4 4 1 6 RR RS RSUT RSU SUR SUTS SUT SU TSUR TS TSUT TSU UR UTS UT UTSU

Korteste vei mellom to gitte punkter min_Vei (w,q,n) u := maxInt FOR i := 1 TO n DO // initiering av q FOR j := 1 TO n DO IF w[i,j] = null THEN q[i,j] := u ELSE q[i,j] := w[i,j] ENDIF ENDFOR FOR k := 1 TO n DO // oppdatering av q FOR i := 1 TO n DO q[i,j] := min (q[i,j], q[i,k] + q[k,j]) 7 5 5

Korteste-vei algoritme Dijkstra - Strategi / Algoritme Dijkstra (source,n) FOR v := 1 TO n DO dist[v] := infinity prev[v] := undefined ENDFOR dist[source] := 0 Q := set of all nodes in Graph finish := false WHILE Q is not empty AND not finished DO u := vertex in Q with smallest dist IF dist[u] = infinity THEN finished := true ELSE remove u from Q FOR each neghbour v of u DO alt := dist[u] + dist_between(u,v) IF alt < dist[v] dist[v] := alt prev[v] := u decrease_key v in Q ENDIF ENDWHILE S T S T S := empty sequence u := target WHILE prev[u] is defined DO insert u at the beginning of S u = prev[v] ENDWHILE

Korteste-vei algoritme Dijkstra - Eks 1 4 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf 4 Korteste-vei algoritme Dijkstra - Eks 2 7 1 5 3 2 3 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf Dijkstra (source,n) FOR v := 1 TO n DO dist[v] := infinity prev[v] := undefined ENDFOR dist[source] := 0 Q := set of all nodes in Graph finish := false WHILE Q is not empty AND not finished DO u := vertex in Q with smallest dist IF dist[u] = infinity THEN finished := true ELSE remove u from Q FOR each neghbour v of u DO alt := dist[u] + dist_between(u,v) IF alt < dist[v] dist[v] := alt prev[v] := u decrease_key v in Q ENDIF ENDWHILE dist prev Q u v alt 1 2 3 4 4 S := empty sequence u := target WHILE prev[u] is defined DO insert u at the beginning of S u = prev[v] ENDWHILE 4 1 1 3 5 3 2

Korteste-vei algoritme Dijkstra - Eks Init 1 4 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf 4 Korteste-vei algoritme Dijkstra - Eks Init 2 7 1 5 3 2 3 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf Dijkstra (source,n) FOR v := 1 TO n DO dist[v] := infinity prev[v] := undefined ENDFOR dist[source] := 0 Q := set of all nodes in Graph finish := false WHILE Q is not empty AND not finished DO u := vertex in Q with smallest dist IF dist[u] = infinity THEN finished := true ELSE remove u from Q FOR each neghbour v of u DO alt := dist[u] + dist_between(u,v) IF alt < dist[v] dist[v] := alt prev[v] := u decrease_key v in Q ENDIF ENDWHILE dist prev Q u v alt 1 inf undef 2 inf undef 3 inf undef 4 inf undef

Korteste-vei algoritme Dijkstra - Eks Init source - Min Heap 1 4 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf 4 Korteste-vei algoritme Dijkstra - Eks Init source - Min Heap 2 7 1 5 3 2 3 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf Dijkstra (source,n) FOR v := 1 TO n DO dist[v] := infinity prev[v] := undefined ENDFOR dist[source] := 0 Q := set of all nodes in Graph finish := false WHILE Q is not empty AND not finished DO u := vertex in Q with smallest dist IF dist[u] = infinity THEN finished := true ELSE remove u from Q FOR each neghbour v of u DO alt := dist[u] + dist_between(u,v) IF alt < dist[v] dist[v] := alt prev[v] := u decrease_key v in Q ENDIF ENDWHILE dist prev Q u v alt 1 inf undef 1 2 inf undef 2 3 inf undef 3 4 0 undef 4

Korteste-vei algoritme Dijkstra - Eks Source 1 4 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf 4 Korteste-vei algoritme Dijkstra - Eks Source 2 7 1 5 3 2 3 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf Dijkstra (source,n) FOR v := 1 TO n DO dist[v] := infinity prev[v] := undefined ENDFOR dist[source] := 0 Q := set of all nodes in Graph finish := false WHILE Q is not empty AND not finished DO u := vertex in Q with smallest dist IF dist[u] = infinity THEN finished := true ELSE remove u from Q FOR each neghbour v of u DO alt := dist[u] + dist_between(u,v) IF alt < dist[v] dist[v] := alt prev[v] := u decrease_key v in Q ENDIF ENDWHILE dist prev Q u v alt 1 inf undef 1 4 2 inf undef 2 3 inf undef 3 4 0 undef

Korteste-vei algoritme Dijkstra - Eks Nabo til node 4 1 4 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf 4 Korteste-vei algoritme Dijkstra - Eks Nabo til node 4 2 7 1 5 3 2 3 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf Dijkstra (source,n) FOR v := 1 TO n DO dist[v] := infinity prev[v] := undefined ENDFOR dist[source] := 0 Q := set of all nodes in Graph finish := false WHILE Q is not empty AND not finished DO u := vertex in Q with smallest dist IF dist[u] = infinity THEN finished := true ELSE remove u from Q FOR each neghbour v of u DO alt := dist[u] + dist_between(u,v) IF alt < dist[v] dist[v] := alt prev[v] := u decrease_key v in Q ENDIF ENDWHILE dist prev Q u v alt 1 inf undef 1 4 2 inf undef 2 3 inf undef 3 4 0 undef dist prev Q u v alt 1 4 4 1 4 1 4 2 inf undef 2 3 inf undef 3 4 0 undef dist prev Q u v alt 1 4 4 1 4 3 1 2 inf undef 2 3 1 4 3 4 0 undef

Korteste-vei algoritme Dijkstra - Eks Nabo til node 3 1 4 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf 4 Korteste-vei algoritme Dijkstra - Eks Nabo til node 3 2 7 1 5 3 2 3 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 4 1 inf Dijkstra (source,n) FOR v := 1 TO n DO dist[v] := infinity prev[v] := undefined ENDFOR dist[source] := 0 Q := set of all nodes in Graph finish := false WHILE Q is not empty AND not finished DO u := vertex in Q with smallest dist IF dist[u] = infinity THEN finished := true ELSE remove u from Q FOR each neghbour v of u DO alt := dist[u] + dist_between(u,v) IF alt < dist[v] dist[v] := alt prev[v] := u decrease_key v in Q ENDIF ENDWHILE dist prev Q u v alt 1 4 4 1 4 3 1 2 inf undef 2 3 1 4 3 4 0 undef dist prev Q u v alt 1 4 4 1 3 2 4 2 4 3 2 3 1 4 4 0 undef

Korteste-vei algoritme Dijkstra - Eks Nabo til node 1 4 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf 4 Korteste-vei algoritme Dijkstra - Eks Nabo til node 1 2 7 1 5 3 2 3 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 4 1 inf Dijkstra (source,n) FOR v := 1 TO n DO dist[v] := infinity prev[v] := undefined ENDFOR dist[source] := 0 Q := set of all nodes in Graph finish := false WHILE Q is not empty AND not finished DO u := vertex in Q with smallest dist IF dist[u] = infinity THEN finished := true ELSE remove u from Q FOR each neghbour v of u DO alt := dist[u] + dist_between(u,v) IF alt < dist[v] dist[v] := alt prev[v] := u decrease_key v in Q ENDIF ENDWHILE dist prev Q u v alt 1 4 4 1 3 2 4 2 4 3 2 3 1 4 4 0 undef dist prev Q u v alt 1 4 4 1 2 9 2 4 3 2 3 1 4 4 0 undef

Korteste-vei algoritme Dijkstra - Eks Nabo til node 2 1 4 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf 4 Korteste-vei algoritme Dijkstra - Eks Nabo til node 2 2 7 1 5 3 2 3 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 4 1 6 Dijkstra (source,n) FOR v := 1 TO n DO dist[v] := infinity prev[v] := undefined ENDFOR dist[source] := 0 Q := set of all nodes in Graph finish := false WHILE Q is not empty AND not finished DO u := vertex in Q with smallest dist IF dist[u] = infinity THEN finished := true ELSE remove u from Q FOR each neghbour v of u DO alt := dist[u] + dist_between(u,v) IF alt < dist[v] dist[v] := alt prev[v] := u decrease_key v in Q ENDIF ENDWHILE dist prev Q u v alt 1 4 4 1 2 9 2 4 3 2 3 1 4 4 0 undef dist prev Q u v alt 1 4 4 2 1 11 2 4 3 3 1 4 4 0 undef dist prev Q u v alt 1 4 4 2 4 6 2 4 3 3 1 4 4 6 2

Korteste-vei algoritme Dijkstra - Eks Gjennomløp av korteste vei 1 4 1 2 3 4 1 inf 5 inf inf 2 7 3 inf inf 3 inf 3 inf inf 4 4 inf 1 inf 4 Korteste-vei algoritme Dijkstra - Eks Gjennomløp av korteste vei 2 7 1 5 3 2 3 Dijkstra (source,n) FOR v := 1 TO n DO dist[v] := infinity prev[v] := undefined ENDFOR dist[source] := 0 Q := set of all nodes in Graph finish := false WHILE Q is not empty AND not finished DO u := vertex in Q with smallest dist IF dist[u] = infinity THEN finished := true ELSE remove u from Q FOR each neghbour v of u DO alt := dist[u] + dist_between(u,v) IF alt < dist[v] dist[v] := alt prev[v] := u decrease_key v in Q ENDIF ENDWHILE dist prev 1 4 4 2 4 3 3 1 4 4 6 2 4 3 2 4 S := empty sequence u := target WHILE prev[u] is defined DO insert u at the beginning of S u = prev[v] ENDWHILE 4 1 1 3 5 3 2

Lenket liste implementering av graf Nabo-liste Punkt Kant-liste (Nabo-liste) A B - C - D B C D D E A - D

Innsetting Start : Start-peker til første punkt i Punkt-listen PLed : Peker til første ledige i Punkt-listen KLed : Peker til første ledige i Kant-listen Pkt : Info-felt i Punkt-listen NPkt : Peker til neste punkt i Punkt-listen FKant: Peker til første kant Pkant: Peker som viser hvilket punkt som svarer til denne kanten NKant: Peker til neste kant

finnElement finnElement (pkt,nPkt,start,post,lok) /* Søker etter posten med innhold post i tabellen pkt */ /* og returnerer med lokasjonen til denne posten. */ /* post : Innhold i søkt Post */ /* lok : Returnerer med lokasjonen (posisjonen) */ /* til søkt Post (returnerer med verdien NULL */ /* hvis posten ikke finnes) */ null := 0 lok := null peker := start WHILE (peker != null) AND (lok = null) DO IF post = pkt[peker] THEN lok := peker ELSE peker := nPkt[peker] ENDIF ENDWHILE

finnKant finnKant(pkt,nPkt,fKant,pKant,nKant,start,post1,post2,lok1,lok2,flag) /* Søker etter en gitt kant i kant-tabellen og returnerer med lokasjonen til denne kanten. */ /* post1 : Første punkt i søkt kant */ /* post2 : Andre punkt i søkt kant */ /* lok1 : Returnerer med lokasjonen (posisjonen) til første punkt i søkt kant */ /* (returnerer med verdien null hvis posten ikke finnes */ /* lok2 : Returnerer med lokasjonen (posisjonen) til andre punkt i søkt kant */ /* (returnerer med verdien null hvis posten ikke finnes) */ /* flag : Returnerer med verdien true hvis det finnes en kant mellom post1 og post2 */ null := 0 flag := false finnElement (pkt,nPkt,start,post1,lok1) finnElement (pkt,nPkt,start,post2,lok2) IF (lok1 != null) AND (lok2 != null) THEN finnElement(pKant,nKant,fKant[lok1],lok2,lok) IF lok != null THEN flag := true ENDIF

innsettPunkt innsettPunkt (pkt,nPkt,fKant,start,pled,post,full) /* Setter inn nytt punkt først i punkt-listen */ /* post : Nytt punkt som skal innsettes */ null:= 0 IF pled = null THEN // Pkt-listen er full full := true ELSE // Ledig plass i Pkt-listen full := false ny := pled pled := nPkt[ny] pkt[ny] := post fKant[ny] := null nPkt[ny] := start start := ny ENDIF

Innsett_Kant innsettKant (pkt,nPkt,fKant,start,pKant,nKant,kLed,p1,p2,full,flag) /* Setter inn ny kant først i kant-listen. ‘/ null := 0 IF kled = null THEN full := true flag := false ELSE full := false finnElement (pkt,nPkt,start,p1,lok1) finnElement (pkt,nPkt,start,p2,lok2) IF (lok1 != null) AND (lok2 != null) THEN ny := kled kLed := nKant[Ny] pKant[Ny] := lok2 nKant[Ny] := fKant[lok1] fKant[Lok1] := ny flag := true ENDIF

fjernElement fjernElement (info,neste,start,led,post,flag) // Fjerner et gitt element i en åpen forlengs liste null := 0 flag := false IF start != null THEN IF post = info[head] THEN // Slette første Post peker := start start := neste[peker] neste[peker] := led led := peker flag := true ELSE // Slette post ute i listen forrige := start peker := neste[start] WHILE (peker != nULL) AND (NOT flag) DO IF post = info[peker] THEN neste[forrige] := neste[peker] neste[peker] := led led := peker flag := true ELSE forrige := peker peker := neste[peker] ENDIF ENDWHILE

fjernPunkt fjernPunkt (pkt,nPkt,fKant,start,pLed,pKant,nKant,kLed,post,flag) /* Fjerner et gitt punkt samt kanter tilhørende dette punktet */ null := 0 finnElement (pkt,nPkt,start,post,lok) // Punktet som skal fjernes IF lok = null THEN Flag := False ELSE peker := start WHILE peker != null DO // Fjern inngående kanter til Post fjernElement (pKant,nKant,fKant[peker],kLed,lok,flag) peker := nPkt[peker] ENDWHILE IF fKant[Lok] != NULL THEN // Fjern utgående kanter fra Post beg := fKant[lok] end := fKantlok] peker := nKant[end] WHILE peker != null DO end := peker peker := nKant[peker] nKant[end] := kLed kLed := beg ENDIF fjernElement (pkt,nPkt,start,pled,post,flag) // Fjern Post

fjernKant fjernKant (pkt,nPkt,fKant,start,pKant,nKant,kLed,p1,p2,flag) /* Fjerner en gitt kant i kant-listen */ /* p1 : Første punkt i kanten som skal slettes */ /* p2 : Andre punkt i kanten som skal slettes */ /* flag : Returnerer med verdien True */ /* hvis slettingen er ok */ finnElement (pkt,nPkt,start,p1,lok1) finnElement (pkt,nPkt,start,p2,lok2) fjernElement (pKant,nKant,fKant[lok1],kLed,lok2,flag)

Klassehierarki - Graf I_Comparable A_Object I_Container A_Container I_Vertex I_Edge I_Vertex Interface for punkter (noder) I_Edge Interface for kanter I_Graph Interface for graf I_Digraph Interface for rettet (ordnet) graf A_Graph Abstrakt klasse for graf GraphAsMatrix Graf implementert som matrise GraphAsList Graf implementert som liste DigraphAsMatrix Rettet (ordnet) graf implementert som matrise DigraphAsList Rettet (ordnet) graf implementert som liste I_Graph A_Graph GraphAsMatrix Test GraphAsList Test I_DiGraph DigraphAsMatrix Test DigraphAsList Test

Interface I_Vertex Interface I_Vertex: getNumber Returnerer nummer til punkt (node) i grafen getWeight Returnerer weight til punkt (node) i grafen getIncidentEdges Returnerer en nummerering av innkommende kanter getEmanatingEdges Returnerer en nummerering av utgående kanter gerPredecessors Returnerer en nummerering av inn-punkter (forutgående punkter) getSuccessors Returnerer en nummerering av ut-punkter (etterfølgende punkter)

Interface I_Edge Interface I_Edge: getV1 Returnerer endepunkt nr 1 (startpunkt) til kanten getV2 Returnerer endepunkt nr 2 (endepunkt) til kanten getWeight Returnerer weight til kanten isDirected Returnerer true hvis kanten er ordnet (rettet) getConnectedVertex Returnerer det andre endepunktet til kanten

Interface I_Graph Interface I_Graph: getNumberOfVertices Returnerer antall punkter (noder) getVertices Returnerer en nummerering av alle punktene getVertex Returnerer punkt for gitt indeks-nummer addVertex Legger inn en nytt punkt, evnt m/weight getNumberOfEdges Returnerer antall kanter getEdges Returnerer en nummerering av alle kantene addEdge Legger inn en ny kant for to oppgitte endepunkter, evnt m/weight getEdge Returnerer kant for gitt to endepunkter isEdge Returnerer true hvis det går en kant mellom to oppgitte endepunkter isDirected Returnerer true hvis grafen er ordnet (rettet) isConnected Returnerer true hvis grafen er sammenhengende isCyclic Returnerer true hvis grafen er syklisk depthFirstTraversal Dybde først gjennomløp breadthFirstTraversal Bredde først gjennomløp

Interface I_Graph Interface I_Digraph: isStronglyConnected Returnerer true hvis grafen er sterk sammenhengende. En uordnet graf sies å være sammenhengende hvis det for hvert par av punkter går en vei mellom disse punktene. En ordnet graf sies å være sterkt sammenhengende hvis det for hvert par av punkter En ordnet graf sies å være svakt sammenhengende hvis det for hvert par av punkter går en vei mellom disse punktene i den underliggende uordnede grafen. topologicalOrderTraversal Gjennomløping grafen i topologisk rekkefølge. En topologisk sortering av en rettet, asyklisk graf er en sekvens S = {v1,v2,…vn} hvor alle noder er med eksakt en gang. For hvert par av distinkte noder vi og vj i S har vi i < j hvis det går en kant fra vi til vj.

Abstrakt klasse A_Graph numberOfVertices Antall punkter i grafen numberOfEdges Antall kanter i grafen vertex Array av punkter size Størrelsen av punkt-arrayen vertex A_Graph Kontstruktør som bl.a. initierer punkt-arrayen Legg merke til at det i den abstrakte klassen A_Graph ikke er lagt inn noe array-attributt edge (på samme måte som for vertex) for å ta vare på alle kantene i grafen. Dette henger sammen med at vi på dette stadiet ikke vet hvordan kantene skal implementeres (som array, liste, …). Et attributt edge vil derfor først komme i arvede klasser fra A_Graph.

A_Graph getNumberOfVertices - getVertex getNumberOfVertices Returnerer antall punkter i grafen gerVertex Returnerer punkt med gitt indeks

A_Graph getVertices getVertices Returnerer en nummerering av alle punktene i grafen. Nummereringen etter fortløpende array-indeks. Ved initiering settes en lokal hjelpevariabel position lik 0. Denne variabelen øker med 1 for hver nytt punkt som hentes frem. hasMoreElements returnerer true hvis position er mindre enn totalt antall punkter i grafen. nextElement henter neste element (objekt) i arrayen vertex og øker deretter position med 1.

A_Graph addVertex addVertex Innlegging i grafen av nytt punkt med gitt nummer m/evnt. vekt (weight).

A_Graph getNumberOfEdges - getEdge – getEdges addEdge - isEdge getNumberOfEdges Returnerer antall kanter i grafen. Følgende metoder er abstrakte (pga at kant-implementeringen på dette trinnet ikke er kjent): getEdge Returnerer kant med to gitte endepunkter getEdges Returnerer en nummerering av alle kantene addEdge Innlegging av ny kant mellom to oppgitte endepunkter m/evnt vekt isEdge Retunerer true hvis det går en kant mellom to oppgitte endepunter

A_Graph depthFirstTraversal depthFirstTraversal Dybde først gjennomløp Først kalles depthFirstTraversal (I_PreInPostVisitor visitor, int start). visitor Er her enten en PreVisitor eller en PostVisitor mht gjennomløpingsrekkefølgen. start Oppgitt startpunkt (indeks) for gjennomløpingen. En lokal array visited settes til false for samtlige punkter i grafen. Denne arrayen skal hjelpe oss til å besøke nodene i tur og orden på en slik måte at alle nodene som kan nåes med utgangspunkt i startnoden besøkes og slik at ikke noen node besøkes mer enn en gang. Deretter kalles depthFirstTraversal (I_PreInPostVisitor visitor, I_Vertex v, boolean[] visited). visitor Visitor nevnt ovenfor. v Punkt svarende til gitt startpunkt (indeks) nevnt ovenfor. visited Array nevnt ovenfor med informasjon om hvorvidt et punkt er besøkt eller ikke. Hvis visitor.isDone( ) returnerer false (gjennomløpingen skal fortsette), besøkes det gitte startpunktet (den gitte startnoden). Hvis visitor er en PreVisitor, så vil metoden preVisit være ikke-tom og noden prosesseres. Visited settes til true for denne noden. Deretter bestemmes alle etterfølgende noder til denne gitte noden. Disse kalles nå opp rekursivt. Metoden postVisit utføres til slutt. Denne er ikke-tom hvis visitor er en PostVisitor. Merk at denne dybde først gjennomløpingen kun gjennomløper alle de punktene (nodene) som kan nåes fra det gitte startpunktet.

A_Graph breadthFirstTraversal breadthFirstTraversal (I_Visitor visitor, int start) Bredde først gjennomløp visitor En visitor av typen I_Visitor. start Oppgitt startpunkt (indeks) for gjennomløpingen. En lokal boolsk array qAdded sette til false for samtlige punkter (noder) i grafen. Merk at denne bredde først gjennomløpingen kun gjennomløper alle de punktene (nodene) som kan nåes fra det gitte startpunktet. En lokal kø queue implementeres som en liste. Denne køen skal hjelpe oss å holde oversikt over alle naboene til en gitt node slik at disse i tur og orden kan besøkes (hvis de ikke allerede tidligere er besøkt eller ligger i køen). For hver node som påtreffes, adderes til køen queue alle denne noden naboer (hvis de ikke allerede finnes i køen eller tidligere har vært i køen).

A_Graph isDirected isDirected Returnerer true hvis grafen er ordnet (rettet). A_Graph er i utgangspunktet tiltenkt uordnede grafer (derfor returnerer metoden isDirected her verdien false). Ordnede grafer er klasser som implementerer interfacet I_Digraph.

A_Graph isConnected Connected: Finnes en vei mellom hvert par av noder. Starter i en fritt valgt node (her node nr 0). Benytter dybdeFørst gjennomløp og teller antall noder som besøkes. Grafen er connected hvis antall besøkte noder er lik totalt antall noder i grafen. isConnected Returnerer true hvis grafen er sammenhengende (connected). En uordnet graf sies å være sammenhengende hvis det for hvert par av punkter går en vei mellom disse punktene. En ordnet graf sies å være sterkt sammenhengende hvis det for hvert par av punkter En ordnet graf sies å være svakt sammenhengende hvis det for hvert par av punkter går en vei mellom disse punktene i den underliggende uordnede grafen. Rutinen starter i en fritt valgt node (her node nr 0). Benytter dybdeFørstgjennomløp og teller antall noder som besøkes. Grafen er sammenhengende (connected) hvis antall besøkte noder er lik totalt antall noder i grafen. Telling av besøkte noder utføres av visit-metoden i visitor som for hvert bøsøk øker en teller (counter) med 1. counter (med synbart attributt value) er en forekomst av en underklasse i klassen A_Graph.

A_Graph isCyclic isCyclic Returnerer true hvis grafen er syklisk. Default returverdi er false (kantene er ikke implementert på dette stadiet).

A_Graph getPredecessors - getSuccessors getIncidentEdges - getEmanatingEdges Følgende metoder er abstrakte (pga at kant-implementeringen på dette trinnet ikke er kjent): getPredecessors Returnerer en nummerering av alle inn-nodene (forutgående noder) getSuccessors Returnerer en nummerering av alle ut-nodene (etterfølgende noder) getIncidentEdges Returnerer en nummerering av alle inn-kantene getEmanatingEdges Returnerer en nummerering av alle ut-kantene

A_Graph.GraphVertex getPredecessors - getSuccessors getIncidentEdges - getEmanatingEdges A_Graph.GraphVertex Klasse for punkter (noder). Underklasse i klassen A_Graph. number node-nummer (punkt-nummer) weight vekt GraphVertex Konstruktør som initierer number og weight

A_Graph.GraphVertex getNumber - getWeight getNumber Returnerer number (node-nummer, punkt-nummer) getWeight Returnerer weight (node-vekt, punkt-vekt)

A_Graph.GraphVertex getPredecessors - getSuccessors getIncidentEdges - getEmanatingEdges Følgende metoder kaller tilhørende abstrakte (pga at kant-implementeringen på dette trinnet ikke er kjent) metoder i A_Graph: getPredecessors Returnerer en nummerering av alle inn-nodene (forutgående noder) getSuccessors Returnerer en nummerering av alle ut-nodene (etterfølgende noder) getIncidentEdges Returnerer en nummerering av alle inn-kantene getEmanatingEdges Returnerer en nummerering av alle ut-kantene

A_Graph.GraphVertex compareTo compareTo Returnerer 0 (denne metoden implementeres på arvede klasser)

A_Graph.GraphEdge getPredecessors - getSuccessors getIncidentEdges - getEmanatingEdges A_Graph.GraphEdge Klasse for kanter. Underklasse i klassen A_Graph. v1 Kantens startpunkt v2 Kantens endepunkt weight Kantens vekt GraphEdge Kontruktør som initierer v1, v2 og weight

A_Graph.GraphEdge getV1 - getV2 - getWeight getV1 Returnerer kantens startpunkt getV2 Returnerer kantens endepunkt getWeight Returnerer kantens vekt

A_Graph.GraphEdge getConnectedVertex – isDirected compareTo getConnectedVertex Returnerer kantens andre punkt når kantens ene punkt er oppgitt.

A_Graph.Counter A_Graph.Counter Underklasse i A_Graph som benyttes til telling i forbindelse med ulike gjennomløp av en graf.

GraphAsMatrix GraphAsMatrix Klasse hvor graf er implementert som matrise matrix 2-dimensjonal matrise for registrering av grafens kanter GraphAsMatrix Konstruktør som oppretter matrise av en gitt størrelse

GraphAsMatrix addEdge addEdge Adderer til en ny kant eventuelt m/vekt-opplysninger. Siden A_Graph er tiltenkt uordnet graf (Digraph benyttes for ordnet graf), vil en ny kant fra v1 til v2 også måtte inkludere en kant fra v2 til v1.

GraphAsMatrix getEdge - isEdge getEdge (int v1, int v2) Returnerer den kanten som går fra v1 til v2. isEdge (int v1, int v2) Returnerer true hvis det går en kant fra v1 til v2.

GraphAsMatrix getEdges getEdges Returnerer en nummerering av samtlige kanter i grafen. Nummereringen utføres radvis fra graf-matrisen.

GraphAsMatrix getPredecessors getPredecessors Returnerer en nummerering av alle forgjengere (inngående punkter) til et gitt punkt.

GraphAsMatrix getSucessors getSuccessors Returnerer en nummerering av alle etterfølgere (utgående punkter) til et gitt punkt.

GraphAsMatrix getIncidentEdges getIncidentEdges Returnerer en nummerering av alle innkantene til et gitt punkt.

GraphAsMatrix getEmanatingEdges getEmanatingEdges Returnerer en nummerering av alle utkantene til et gitt punkt.

GraphAsList GraphAsList Klasse hvor graf er implementert vha lister list 1-dimensjonal array for registrering av grafens kanter. Hver node (hvert punkt) i grafen er tilordnet en liste for registrering av alle kanter som går ut fra denne noden. Hver av disse listene er forekomster av DList (dobbelt lenket sirkulær liste med dummy-element). GraphAsList Konstruktør som oppretter en tom liste (forekomst av DList) for hver node (hvert punkt) i grafen. Hver av listene er i utgangspunktet tomme lister.

GraphAsList addEdge addEdge Adderer til en ny kant eventuelt m/vekt-opplysninger. Siden A_Graph er tiltenkt uordnet graf (Digraph benyttes for ordnet graf), vil en ny kant fra v1 til v2 også måtte inkludere en kant fra v2 til v1.

GraphAsList getEdge getEdge (int v1, int v2) Returnerer kanten som går fra v1 til v2.

GraphAsList isEdge isEdge (int v1, int v2) Returnerer true hvis det går en kant fra v1 til v2.

GraphAsList getEdges (1/3) getEdges Returnerer en nummerering av alle kantene i grafen.

GraphAsList getEdges (2/3)

GraphAsList getEdges (3/3)

GraphAsList getPredecessors (1/3) getPredecessors Returnerer en nummerering av alle forgjengere (inngående punkter) til et gitt punkt.

GraphAsList getPredecessors (2/3) getPredecessors Returnerer en nummerering av alle forgjengere (inngående punkter) til et gitt punkt.

GraphAsList getPredecessors (3/3) getPredecessors Returnerer en nummerering av alle forgjengere (inngående punkter) til et gitt punkt.

GraphAsList getSucessors getSuccessors Returnerer en nummerering av alle etterfølgere (utgående punkter) til et gitt punkt.

GraphAsList getIncidentEdges (1/3) getIncidentEdges Returnerer en nummerering av alle innkantene til et gitt punkt.

GraphAsList getIncidentEdges (2/3) getIncidentEdges Returnerer en nummerering av alle innkantene til et gitt punkt.

GraphAsList getIncidentEdges (3/3) getIncidentEdges Returnerer en nummerering av alle innkantene til et gitt punkt.

GraphAsList getEmanatingEdges getEmanatingEdges Returnerer en nummerering av alle utkantene til et gitt punkt.

DigraphAsMatrix DigraphAsMatrix - addEdge - isDirected DigraphAsMatrix Klasse hvor ordnet graf er implementert som en matrise. DigraphAsMatrix Konstruktør for oppretting av en matrise av gitt størrelse. addEdge Adderering av en ny kant til grafen. isDirected Returnerer true siden vi her opererer med en ordnet (rettet) graf.

DigraphAsMatrix topologicalOrderTraversal (1/3) S = {A,B,C,D,E,F} S = {A,C,B,E,F,D} B D DigraphAsMatrix topologicalOrderTraversal (1/3) A F C E En topologisk sortering av en rettet, asyklisk graf er en sekvens S = {v1,v2,…vn} hvor alle noder er med eksakt en gang. For hvert par av distinkte noder vi og vj i S har vi i < j hvis det går en kant fra vi til vj. Strategi: WHILE flere noder velg en node med inngrad 0 (må finnes minst en slik hvis asyklisk graf) adder noden til sortering S slett noden og alle tilhørende utgående kanter fra grafen ENDWHILE En topologisk sortering av en rettet, asyklisk graf er en sekvens S = {v1,v2,…vn} hvor alle noder er med eksakt en gang. For hvert par av distinkte noder vi og vj i S har vi i < j hvis det går en kant fra vi til vj. Følgende strategi kan benyttes for å lage en topologisk sortering: 1. Velg en node med inngrad 0 (det må finnes minst en slik når grafen er asyklisk). 2. Adder noden til den topologiske sorteringen S. 3. Slett noden og alle tilhørende utgående kanter fra grafen. Gjenta punktene 1., 2. og 3. for alle de resterende nodene. Fjerning av en node og tilhørende utgående kanter kan simuleres ved å senke inngraden med 1 for alle etterfølgende noder. Denne fremgangsmåten blir benyttet i rutinen på neste side. Fjerning av en node og tilhørende utgående kanter kan simuleres ved å senke inngrad med 1 for alle etterfølgende noder.

DigraphAsMatrix topologicalOrderTraversal (2/3) S = {A,B,C,D,E,F} S = {A,C,B,E,F,D} B D DigraphAsMatrix topologicalOrderTraversal (2/3) A F C E En topologisk sortering av en rettet, asyklisk graf er en sekvens S = {v1,v2,…vn} hvor alle noder er med eksakt en gang. For hvert par av distinkte noder vi og vj i S har vi i < j hvis det går en kant fra vi til vj. topologicalOrderTraversal gjennomløper en graf i samsvar med en topologisk sortering.

DigraphAsMatrix topologicalOrderTraversal (3/3) S = {A,B,C,D,E,F} S = {A,C,B,E,F,D} B D DigraphAsMatrix topologicalOrderTraversal (3/3) A F C E topologicalOrderTraversal - Inngrad til samtlige noder settes lik 0. - Vha getEdges gjennomløpes alle grafens kanter for bestemmelse av samtlige noders inngrad. - Samtlige noder med inngrad 0 adderes til en kø queue. - Vha en while-sløyfe gjennomløpes alle noder med inngrad 0. For hver node eksekveres visit-metoden til en gitt visitor. For hver node bestemmes (vha getSuccessors) alle etterfølgende noder. Inngraden for disse sistnevnte senkes med 1. Hvis inngraden nå blir 0, adderes noden til køen queue.

DigraphAsMatrix isStronglyConnected Finnes en vei mellom hvert par av noder. Foretar en start i hver av nodene og benytter dybde først gjennomløp. Strongly connected hvis hvert gjennomløp besøker alle nodene i grafen. isStronglyConnected Returnerer true hvis grafen er strongly connected. En ordnet graf sies å være strongly connected hvis det finnes en vei mellom hvert par av noder. Foretar en start i hver av nodene og benytter dybde først gjennomløp. Hvis hvert gjennomløp besøker alle nodene i grafen, så er grafen strongly connected. En ordnet graf sies å være weakly connected hvis det finnes en vei mellom hvert par av noder i den underliggende uordnede grafen.

DigraphAsMatrix isCyclic isCyclic Returnerer true hvis grafen er syklisk. Strategi: - Lager en visitor hvor visit-metoden for hvert treff på en node øker en teller (counter.value) med 1. - Gjennomløper grafen i topologisk orden med denne visitor’en. - Grafen er syklisk hvis antall besøkte noder er ulik totalt antall noder i grafen.

DigraphAsList DigraphAsList - addEdge - isDirected DigraphAsList Klasse hvor ordnet graf er implementert vha lister. Hver node (hvert punkt) i grafen er tilordnet en liste for registrering av alle kanter som går ut fra denne noden. Hver av disse listene er forekomster av DList (dobbelt lenket sirkulær liste med dummy-element). DigraphAsList Konstruktør for oppretting av en matrise av gitt størrelse. super kaller konstruktør i superklassen GraphAsList som oppretter en tom liste (forekomst av DList) for hver node (hvert punkt) i grafen. Hver av listene er i utgangspunktet tomme lister. addEdge Adderering av en ny kant til grafen. isDirected Returnerer true siden vi her opererer med en ordnet (rettet) graf.

DigraphAsList topologicalOrderTraversal (1/2) S = {A,B,C,D,E,F} S = {A,C,B,E,F,D} B D DigraphAsList topologicalOrderTraversal (1/2) A F C E En topologisk sortering av en rettet, asyklisk graf er en sekvens S = {v1,v2,…vn} hvor alle noder er med eksakt en gang. For hvert par av distinkte noder vi og vj i S har vi i < j hvis det går en kant fra vi til vj. topologicalOrderTraversal gjennomløper en graf i samsvar med en topologisk sortering Følgende strategi kan benyttes for å lage en topologisk sortering: 1. Velg en node med inngrad 0 (det må finnes minst en slik når grafen er asyklisk). 2. Adder noden til den topologiske sorteringen S. 3. Slett noden og alle tilhørende utgående kanter fra grafen. Gjenta punktene 1., 2. og 3. for alle de resterende nodene.

DigraphAsList topologicalOrderTraversal (2/2) S = {A,B,C,D,E,F} S = {A,C,B,E,F,D} B D DigraphAsList topologicalOrderTraversal (2/2) A F C E topologicalOrderTraversal - Inngrad til samtlige noder settes lik 0. - Vha getEdges gjennomløpes alle grafens kanter for bestemmelse av samtlige noders inngrad. - Samtlige noder med inngrad 0 adderes til en kø queue. - Vha en while-sløyfe gjennomløpes alle noder med inngrad 0. For hver node eksekveres visit-metoden til en gitt visitor. For hver node bestemmes (vha getSuccessors) alle etterfølgende noder. Inngraden for disse sistnevnte senkes med 1. Hvis inngraden nå blir 0, adderes noden til køen queue.

DigraphAsList isStronglyConnected isStronglyConnected Returnerer true hvis grafen er strongly connected. En ordnet graf sies å være strongly connected hvis det finnes en vei mellom hvert par av noder. Foretar en start i hver av nodene og benytter dybde først gjennomløp. Hvis hvert gjennomløp besøker alle nodene i grafen, så er grafen strongly connected. En ordnet graf sies å være weakly connected hvis det finnes en vei mellom hvert par av noder i den underliggende uordnede grafen.

DigraphAsList isCyclic isCyclic Returnerer true hvis grafen er syklisk. Strategi: - Lager en visitor hvor visit-metoden for hvert treff på en node øker en teller (counter.value) med 1. - Gjennomløper grafen i topologisk orden med denne visitor’en. - Grafen er syklisk hvis antall besøkte noder er ulik totalt antall noder i grafen.

Test_GraphAsMatrix (1/2) Test_GraphAsMatrix Test-program for klassen GraphAsMatrix. Noder og kanter blir generert og lagt inn i grafen slik at grafen blir som vist på figuren til høyre.

Test_GraphAsMatrix (2/2) Test_GraphAsMatrix Test-program for klassen GraphAsMatrix. En while-sløyfe gjennomløper (vha nummereringen getVertices (som nummererer alle nodene i grafen )) og skriver ut alle nodene. En while-sløyfe gjennomløper (vha nummereringen getEdges (som nummererer alle kantene i grafen )) og skriver ut alle kantene. En test avgjør hvorvidt grafen er sammenhengende (connected) eller ikke.

Test_GraphAsList (1/5) Test_GraphAsList Test-program for klassen GraphAsList. Noder og kanter blir generert og lagt inn i grafen slik at grafen blir som vist på figuren til høyre.

Test_GraphAsList (2/5) Test_GraphAsList Test-program for klassen GraphAsList. Vha getEdge skrives ut den kanten som går fra node nr 0 til node nr 3. Vha isEdge testes hvorvidt det går en kant fra node nr 2 til node nr 4.

Test_GraphAsList (3/5) Test_GraphAsList Test-program for klassen GraphAsList. En while-sløyfe gjennomløper (vha nummereringen getVertices (som nummererer alle nodene i grafen )) og skriver ut alle nodene. En while-sløyfe gjennomløper (vha nummereringen getEdges (som nummererer alle kantene i grafen )) og skriver ut alle kantene. En test avgjør hvorvidt grafen er sammenhengende (connected) eller ikke.

Test_GraphAsList (4/5) Test_GraphAsList Test-program for klassen GraphAsList. En while-sløyfe gjennomløper (vha nummereringen getSuccessors (som nummererer alle etterfølgende noder til node nr 0 )) og skriver ut alle etterfølgende noder. En while-sløyfe gjennomløper (vha nummereringen getEdges (som nummererer alle utkantene fra node nr 0)) og skriver ut alle ut-kantene.

Test_GraphAsList (5/5) Test_GraphAsList Test-program for klassen GraphAsList. En while-sløyfe gjennomløper (vha nummereringen getPredecessors (som nummererer alle forutgående noder til node nr 0 )) og skriver ut alle etterfølgende noder. En while-sløyfe gjennomløper (vha nummereringen getIncidentEdges (som nummererer alle innkantene til node nr 0)) og skriver ut alle inn-kantene.

Test_DigraphAsMatrix (1/2) Test_DigraphAsMatrix Test-program for klassen DiGraphAsMatrix. Noder og kanter blir generert og lagt inn i grafen slik at grafen blir som vist på figuren til høyre.

Test_DigraphAsMatrix (2/2) Test_DigraphAsMatrix Test-program for klassen DiGraphAsMatrix. Noder og kanter blir generert og lagt inn i grafen slik at grafen blir som vist på figuren til høyre. En test avgjør hvorvidt grafen er syklisk. En test avgjør hvorvidt grafen er strongly connected.

Test_DigraphAsList (1/2) Test_DigraphAsList Test-program for klassen DiGraphAsList. Noder og kanter blir generert og lagt inn i grafen slik at grafen blir som vist på figuren til høyre.

Test_DigraphAsList (2/2) Test_DigraphAsList Test-program for klassen DiGraphAsList. En test avgjør hvorvidt grafen er syklisk. En test avgjør hvorvidt grafen er strongly connected.

Kritisk vei-analyse 1. Minimum tid for gjennomføring av hele prosjektet. 2. Aktivitets-slakk uten endring av total tid. Kritisk vei-analyse Aktivitets-node-graf (node-vektet graf) B1 E9 Tidligst Senest Slakk A 0 0 0 B 3 6 3 C 3 3 0 D 7 7 0 E 8 8 0 F 8 12 4 G 17 17 0 A3 D1 G2 C4 F5 Sett inn dummy-kant / dummy-node når en aktivitet avhenger av mer enn en forgjenger. Kritisk vei-analyse. En ordnet asyklisk graf kan benyttes til å representere et prosjekt som består av ulike delprosjekter og hvor enkelte delprosjekter er avhengig av andre ferdig utførte delprosjekter. Eks: Ved bygging av hus, må grunnmuren settes opp og være ferdig før snekkeren kan begynne. Snekkeren må i sin tur være ferdig med deler av sitt arbeid før elektriker kan begynne osv. I figuren ovenfor til venstre vises grafen til et slikt prosjekt og hvor de enkelte delprosjektene er A, B, C, D, E, F og G. Delprosjekt A (som tar 3 timer (eller 3 dager, …)) må gjennomføres først og må være ferdig avsluttet før delprosjektene B og C starter. Delprosjekt B tar 1 time og delprosjekt C tar 4 timer. Delprosjekt D (som tar 1 time) kan starte når B og C begge er ferdige. Delprosjektene E (som tar 9 timer) og F (som tar 5 timer) kan påbegynnes når D er ferdig. Delprosjekt G (som tar 2 timer) kan påbegynnes når delprosjektene E og F begge er ferdige. Ved kritisk vei-analyse ønsker vi nå å få svar på følgende to spørsmål: 1. Hva er den minste tiden hele prosjektet kan gjennomføres på? 2. Hvor mye tid kan de enkelte delprosjektene sløse bort (eller hvor lang tid kan starten av delprosjektene utsettes) uten at dette får noen innvirkning på tiden for prosjektgjennomføring som helhet? For et relativt enkelt prosjekt som vist i eksemplet ovenfor, kan vi manuelt finne svar på disse to spørsmålene: 1. Totaltid i antall timer: 3 (A) + 4 (C) + 1 (D) + 9 (E) + 2 (G) = 19 2. B kan utsette starttidspunkt med 3 timer (siden B bruker 1 time, mens C bruker 4 timer og D kan ikke starte før begge disse er ferdig. F kan utsette starttidspunkt med 4 timer (siden F bruker 5 timer, mens E bruker 9 timer og G kan ikke starte før begge disse er ferdig. Tabellen til høyre viser en oversikt over tidligst mulig startpunkt for hver av delprosjektene (vi antar at A starter ved tiden 0). Videre vises seneste starttidspunkt for hver av delprosjektene når total prosjekttid skal være upåvirket. Lengst til høyre vises hvor mye hvert delprosjekt kan somle (slakk). I mer kompliserte prosjekter kan det bli vanskelig å skaffe seg en slik oversikt manuelt. Vi ønsker derfor at et dataprogram skal løse problemet for oss. Flere av våre graf-rutiner er basert på å håndtere grafer hvor kantene (og ikke nodene) er tillagt vekt. Vi må derfor først gjøre om fra en aktivitets-node-graf (node-vektet graf) til en event-node-graf (kant-vektet graf). Dette kan formaliseres og derfor utføres av et dataprogram, men her har vi utført denne omformingen manuelt (se fig nederst til høyre). Start-noden A og slutt-noden G er begge omgjort til 2 noder, en som representerer starten av delprosjektet og en som representerer slutten av delprosjektet. Kanten mellom en slik start- og slutt-node er da tiden det tar å gjennomføre dette delprosjektet. Videre må vi også lage en tilsvarende ekstra node for hver node som er avhengig av (har innkanter fra) mer enn en node (eks D må representeres ved en ekstra node siden D er avhengig av at både B og C er ferdig). Merk at kantene fra B-D og C-D begge har vekt 0 (tar 0 tid fra disse er ferdig til D kan begynne). Event-node-graf (kant-vektet graf) B1 E9 A3 D1 G2 C4 F5

Kritisk vei-analyse 1. Minimum tid for gjennomføring av hele prosjektet. 2. Aktivitets-slakk uten endring av total tid. Kritisk vei-analyse Event-node-graf (kant-vektet graf) 3 7 Tidligst Senest Slakk 0 0 0 3 3 0 4 7 3 7 7 0 8 8 0 17 17 0 13 17 4 10 19 19 0 B1 E9 A3 D1 G2 1 2 5 6 9 10 C4 F5 4 8 Tabellen til høyre lager vi nå på følgende måte: Tidligst: Vi lager oss en EarliestTimeVisitor som genererer kolonnen Tidligst vist ovenfor. Denne visitoren har vi med som parameter i et topologisk orden gjennomløp. For hver node beregner vi tidligst mulige startpunkt ved å se på tidligst mulige starttidspunkt for alle forutgående noder og tid for gjennomføring av hver av de forutgående nodene (disse siste opplysningene ligger som informasjon i alle inn-kantene). Senest: Vi lager oss en LatestTimeVisitor som genererer kolonnen Senest vist ovenfor. Denne gang gjennomløper vi grafen baklengs i forhold til tidligst-situasjonen ovenfor. Seneste starttidspunkt for G må jo være lik tidligste starttidspunkt for G (dvs her 17). Seneste starttidspunkt for de øvrige nodene (F, E, D, C, B, A) i denne rekkfølge finner vi nå ved å se på tidligste starttidspunkt for etterfølgende noder samt tiden knyttet til utgående kanter. Et slikt baklengs gjennomløp kan gjennomføres ved dybdeførst gjennomløp med en PostOrder-forekomst-parameter som har LatestTimeVisitor som parameter. Merk altså: depthFirstTraversal(I_PreInPostVisitor postVisitor) ekvivalent med invers topologicalOrderTraversal (I_Visitor visitor). Slakk: Elementene i denne kolonnen bestemmes ved differensen mellom Senest og Tidligst. Kritisk vei 3 B1 E9 A3 D1 G2 C4 F5 4

Kritisk vei-analyse topologicalOrderTraversal Earliest time: 3 Kritisk vei-analyse B1 E9 A3 D1 G2 C4 F5 4 Earliest time: topologicalOrderTraversal med EarliestTimeVisitor C(v1,w) Ev1 Ew Evn C(vn,w) Latest time: reverse topologicalOrder: depthFirstTraversal med PostOrden LatestTimeVisitor Matematisk formulering av betraktningene fra foregående side. Ew Tidligste starttidspunkt for node nr w Lw Seneste starttidspunkt for node nr w vi Startnode (som starter ved tidspunkt 0) vf Sluttnode C(v,w) Vekten (tiden) for kanten som går fra node v til node w P(w) Innkommende kanter til noden w E(w) Utgående kanter fra noden w C(v1,w) Lv1 Slack time: Lw C(vn,w) Lvn

END End.