Plan Algoritmer og datastrukturer Toppunkter Introduktion Philip Bille Algoritme Algoritme Algoritme Algoritmer og datastrukturer Eks: Max i tabel Hvad er det? Algoritmisk problem: præcist defineret relation mellem input og output. Algoritme: metode til at løse et algoritmisk problem. Beskrevet i diskrete og entydige skridt. Matematisk abstraktion af program. Datastruktur: Metode til at organise data så det kan søges i eller manipuleres. 9 9 0 Maxproblemet: givet en tabel A[..n] find et tal i, således at A[i] er maksimal. Input: tabel A[..n]. Output: et tal i, i n, så A[i] A[j] for alle indgange j i. Algoritme til maxproblemet: Gennemløb A og vedligehold nuværende maximale indgang. Returner den til slut.
Beskrivelse af algoritmer Naturligt sprog. Program. public static int findmax(int[] A) { int max = 0; for(i=0; i< n; i++) if (A[i] > A[max]) max = i; return max; } int findmax(int* A, n) { int max = 0; for(i=0; i< n; i++) if (A[i] > A[max]) max = i; return max; } Pseudokode. def findmax(a): max = 0 for i in range(len(a)): if A[i] > A[max]: max = i return max fun findmax [] = raise Empty findmax [x] = x findmax (x::xs) = max(x, findmax xs) Pseudokode Beskrivelse af algoritmer FindMax(A, n) max = 0 for i = to n if (A[i] > A[max]) then max = i return max Naturligt sprog, pseudokode eller program? Som (imperativt) programmeringssprog men uden sprogspecifikke ting. Nemt at implementere og analysere.
Toppunkter 9 9 0 Toppunkter Lad A[..n] være en tabel. En indgang A[i] er et toppunkt hvis det ikke er mindre end dets naboer: A[i-] A[i] A[i+] A[] toppunkt hvis A[] A[] og A[n] er toppunkt hvis A[n-] A[n]. (Tænk A[0] = A[n+] = - ) Toppunkter Algoritme 9 9 0 9 9 0 Toppunktsproblemet: Givet en tabel A[..n] find et tal i, således at A[i] toppunkt. For hver indgang i A, check om den er et toppunkt. Returner det første toppunkt. Som input/output relation: Input: En tabel A[..n]. Output: Et tal i, i n, så A[i] er et toppunkt.
Pseudokode Teoretisk analyse Toppunkt(A, n) if A[] A[] return for i = to n- if A[i-] A[i] A[i+] return i if A[n-] A[n] return n T(n) = antallet af skridt som en algoritmen udfører på et input af størrelse n. Skridt = Læsning/skrivning til hukommelse (x := y, A[i], i++,...), aritmetiske/ boolske operationer (+,-,*,/,%,&&,, &,, ^,~), sammenligninger (<,>,,, =, ) og program-flow (if-then-else, while, for, goto, funktionskald,..) T(n) kaldes tidskompleksiten eller køretiden af algoritmen. Interesseret (næsten altid) i værstefaldstidskompleksitet = maksimal køretid over alle input af størrelse n. Køretid Eksperimentiel analyse Toppunkt(A, n) if A[] A[] return for i = to n- if A[i-] A[i] A[i+] return i if A[n-] A[n] return n c (n-) c c Hvordan opfører algoritmen sig i praksis? Passer den teoretisk analyse med den eksperimentielle analyse? T(n) = c + (n-) c + c T(n) er lineær funktion af n: T(n) = an + b, for passende konstanter a,b>0 I asymptotisk notation: T(n) = Θ(n)
0 Alg Algoritme Givet en tabel A[..n] løser Algoritme toppunktsproblemet i Θ(n) tid., Stemmer overens med praksis. sek. for 000 kørsler Kan vi gøre det bedre?, 0 00k 00k 00k 00k 900k.m.m.m.m.9m tabel str. Algoritme Algoritme 9 9 0 findmax(a, n) max = for i = to n if A[i] > A[max] max = i return max c n c c Algoritme = FindMax Det maximale element er også et toppunkt. T(n) = c + n c + c = Θ(n) Samme asymptotisk køretid som algoritme. Bedre konstanter?
0 Alg Alg Algoritme Givet en tabel A[..n] løser Algoritme toppunktsproblemet i Θ(n) tid., Er hurtigere i praksis en algoritme. sek. for 000 kørsler Kan vi gøre det betydeligt bedre?, 0 00k 00k 00k 00k 900k.m.m.m.m.9m tabel str. 9 9 0 Algoritme Snedig ide: Kig på en vilkårligt indgang A[i] og dens naboer A[i-] og A[i+]. A[i] er et toppunkt => returner i. Ellers: A er lokalt voksende i mindst en retning. => Der findes et toppunkt i den voksende retning. 9 9 0 Kig på miderste indgang A[m] og dens naboer A[m-] og A[m+]. A[m] er et toppunkt => returner m. Ellers: A er lokalt voksende i mindst en retning. Find toppunkt i en lokalt voksende retning rekursivt. => Vi kan smide resten af tabellen væk og stå tilbage med enten A[..i-] eller A[i+..n].
Toppunkt(A,i,j) m = floor((i+j)/) if A[m-] A[m] A[m+] return m elseif A[m-] > A[m] return Toppunkt(A,i,m-) elseif A[m] < A[m+] return Toppunkt(A,m+,j) Kig på miderste indgang A[m] og dens naboer A[m-] og A[m+]. A[m] er et toppunkt => returner m. Ellers: A er lokalt voksende i mindst en retning. Find toppunkt i en lokalt voksende retning rekursivt. Køretid Et rekursivt kald tager konstant tid. Hvormange rekursive kald laver vi? Et rekursivt kald halverer størrelsen af tabellen vi kigger på. Vi stopper når tabellen har størrelse.. rekursive kald: n/. rekursive kald: n/. k te. rekursive kald: n/ k. => Efter log n rekursive kald har tabellen størrelse. => Køretiden er Θ(log n) 0 Alg Alg Alg Algoritme Givet en tabel A[..n] løser Algoritme toppunktsproblemet i Θ(log n) tid. sek. for 000 kørsler, Meget, meget hurtigere end algoritme og., 0 00k 00k 00k 00k 900k.m.m.m.m.9m tabel str.
Opsummering Algoritmer og datastrukturer Toppunkter Algoritme Algoritme Algoritme Søgning og Sortering Philip Bille Plan Søgning Linæer søgning Binær søgning Sortering Indsættelsesortering Søgning Flettesortering
Søgning Lineær søgning 0 9 0 0 9 0 En tabel A[..n] er sorteret (i ikke-faldende rækkefølge) hvis A[] A[] A[n] Søgningsproblemet: Givet en sorteret tabel A og et tal x, afgør om der findes indgang i, så A[i] = x. Undersøg for alle indgange A[i] om A[i] = x. Tid: Θ(n) Binær søgning Analyse Kig på midterste indgang m i A. A[m] = x: færdig A[m] < x: fortsæt rekursivt på højre halvdel. A[m] > x: fortsæt rekursivt på venstre halvdel. Stopper når tabellen har størrelse Hvor hurtigt kører den? Analog til analyse af rekursiv toppunktsalgoritme. Et rekursivt kald tager konstant tid. I hver rekursion halverer vi tabellen vi kigger på. Vi stopper når tabellen har størrelse. Køretiden er Θ(log n)
Alternativ analyse T (n) = ( T (n/) + c hvis n> d hvis n = Lad T(n) være køretiden for binær søgning. Opskriv og udregn rekursionsligningen for T(n). T (n) = ( T (n/) + c hvis n> d hvis n = n T (n) =T + c n = T + c + c n = T + c + c + c. n = T k + ck. n = T log n + c log n = T () + c log n = d + c log n = (log n) Søgning Lineær søgning løser søgningsproblemet i Θ(n) tid. Binær søgning løser søgningsproblemet i Θ(log n) tid. Sortering
Sortering Anvendelser 0 0 Sorteringsproblemet: Givet en tabel A[..n] returner en tabel B[..n] med samme indhold som A men i sorteret orden. Oplagte: Sortere en liste af navne, organisere et MP bibliotek, vise Google PageRank resultater, vise Facebook feed i kronologisk rækkefølge. Ikke oplagte: Datakompression, computergrafik, bioinformatik, anbefalingssystemer (film på Netflix, bøger på Amazon, reklamer på Google,..). Nemme problemer for sorteret data: Binær søgning, find median, identificer duplikater, find tætteste par, find statiske perifere observationer (outliers). Indsættelsessortering (insertion-sort) Korrekthed Start med en ikke sorteret tabel. Kig på indgangene fra venstre til højre. Ved indgang i: Indsæt A[i] i rækkefølge blandt deltabellen A[..i-]. For at finde rette sted sammenligner vi med indgangene fra højre til venstre. Hvorfor virker det? Før iteration i består deltabellen A[..i-] af de tal der oprindeligt var i A[..i-] i sorteret rækkefølge. Iteration i indsætter A[i] i deltabellen A[..i-] Efter iteration i består deltabellen A[..i] af de tal der oprindeligt var i A[..i]
Analyse Analyse Hvor hurtigt kører den? Indsættelsessortering kører i Θ(n ) tid. Hvor lang tid tager det at indsætte A[i] i korrekt position? Samlet tid = Θ(tid for at indsætte alle indgangene i korrekt position) Flettesortering (mergesort) Fletning (merge) Hurtigere sorteringsalgoritme. Ide: Rekursiv sortering vha. fletning af sorterede deltabeller. Mål. Kombiner to sorterede tabeller til én sorteret tabel i lineær tid Ide: Hold styr på mindste element i hver sorteret tabel. Indsæt mindste af de to elementer i en ekstra tabel. Gentag indtil færdig.
Analyse Flettesortering Hvert skridt i algoritmen tager Θ() tid. I hvert skridt flytter vi en indgang frem i en af tabellerne. Linæer tid i sum af længde af tabellerne. Del A i to halvdele. Sorter hver halvdel rekursivt. Flet de to halvdele sammen. Stop når tabel har størrelse
Analyse Lad T(n) være køretiden af flettesortering. Hvor hurtigt kører den? Ide: T(n) = Θ(total tid brugt på fletning) Fletning tager lineær tid. T(n) = Θ(total længde af tabeller over alle rekursive kald)
Analyse Flettesorting kører i Θ(nlog n) tid. Del og hersk (divide-and-conquer) Sortering Flettesortering er eksempel på en del-og-hersk algoritme. Del-og-hersk: algoritmisk designparadigme Del: Opdel problemet i et eller flere delproblemer Indsættelsessortering i Θ(n ) tid. Flettesortering i Θ(nlog n) tid. Fletning i Θ(n) tid. Hersk: Løs delproblemerne rekursivt Kombiner: Sæt løsningerne til delproblemerne sammen til en samlet løsning for problemet. Flettesortering: Del: Del A i to halvdele. Hersk: Sorter hver halvdel rekursivt. Kombiner: Flet de to halvdele sammen.
Opsummering Søgning Linæer søgning Binær søgning Sortering Indsættelsesortering Flettesortering Analyse af algoritmer Philip Bille Plan Teoretisk analyse af algoritmer Køretid Pladsforbrug Asymptotisk notation O, Θ og Ω-notation. Analyse af algoritmer Eksperimentiel analyse af algoritmer
Analyse af algoritmer Analyse af algoritmer Hvorfor virker min algoritme ikke? Hvorfor kører min algoritme så langsomt? Hvorfor løber min algoritme tør for hukommelse? Analyser om en algoritme er korrekt. Robusthed + sikkerhed Analyser hvor mange resourcer en algoritme bruger. Tid Plads Cache-misses Båndbredde... Primært fokus er tid og plads. Analyse af algoritmer Køretid Teoretisk analyse Eksperimentiel analyse T(n) = antallet af skridt som en algoritmen udfører på et input af størrelse n. Skridt: Læsning/skrivning til hukommelse (x := y, A[i], i = i +,...) Arithmetiske/boolske operationer (+,-,*,/,%,&&,, &,, ^,~) Sammenligninger (<,>,=<, =>, =, ) Programflow (if-then-else, while, for, goto, funktionskald,..) T(n) kaldes tidskompleksiten eller køretiden af algoritmen.
Køretid Pladsforbrug Værstefalds-køretid (eng: worst-case running time): maksimal køretid over alle input af størrelse n. Bedstefalds-køretid (eng: best-case running time): minimal køretid over alle input af størrelse n. Gennemsnitlige-køretid (eng: average-case running time): gennemsnitlig køretid over alle input af størrelse n. S(n) = antallet af lagerpladser som algoritmen bruger. Variable og pointere = lagerplads. Tabel af længde x = x lagerpladser. S(n) kaldes pladskompleksiten eller pladsforbruget af algoritmen. Køretid = værstefaldskøretid (medmindre vi eksplicit skriver andet). Findes også amortiseret, randomiseret, etc. køretider. Asymptotisk notation O, Θ og Ω-notation. Notation til at give grænser for funktioners asymptotiske vækst. Velegnet til analyse af algoritmer. Asymptotisk notation
O-notation f(n) er O(g(n)) hvis f(n) cg(n) for store n Eksempel: f(n) er O(n ) hvis f(n) cn for store n. n er O(n )? n n for store n. n + er O(n )? n + n for store n. n + n er O(n )? cg(n) f(n) n + n n for store n. n + n er O(n )? n + n = n n for store n. n er O(n )? n cn for alle konstanter c for store n. f(n) er O(g(n)) hvis der findes konstanter c, n0 > 0, således at for alle n n0 gælder at f(n) cg(n) Notation Hvis f(n) er O(g(n)) skriver vi f(n) = O(g(n)). O(g(n)) er en mængde af funktioner. cg(n) Tænk på = som eller. Man kan skrive f(n) = O(n ) men ikke O(n ) = f(n). f(n) n0
Opgaver f(n) er Ω(g(n)) hvis der findes konstanter c, n0 > 0, således at for alle n n0 gælder at f(n) cg(n) f(n) = n + n - n f(n) = O(n)? f(n) = O(n )? f(n) = O(n )? g(n) = n + log n g(n) = O(n log n)? g(n) = O(n )? g(n) = O(f(n))? f(n) cg(n) f(n) = O(g(n))? n0 f(n) er Θ(g(n)) hvis f(n) er både O(g(n)) og Ω(g(n)) Flere opgaver Hvilke påstande gælder? n log n = O(n ) c g(n) f(n) c g(n) n + n = Ω(n ) n (n - )/ = Θ(n ) n /00 = Ω(n) n /00 + log n = Θ(n ) log n = O(n) log n + n + = Ω(log n)
Egenskaber Typiske køretider a 0 + a n + a n + + a d n d = (n d ) log a (n) = log b n log b a = (log c(n)) for alle konstanter a, b > 0 log(n) =O(n d ) for alle d>0 n d = O(r n ) for alle d>0 og r> for i = to n < Θ() tids operation > for i = to n for j = to n < Θ() tids operation > for i = to n for j = i to n < Θ() tids operation > Typiske køretider T (n) = ( T (n/) + () hvis n> () hvis n = T (n) = ( T (n/) + (n) hvis n> () hvis n = Eksperimentiel analyse T (n) = ( T (n/) + (n) hvis n> () hvis n = T (n) = ( T (n/) + () hvis n> () hvis n =
Eksperimentiel analyse Eksempel Hvad hvis man ikke kender teoretisk køretid. Kan man finde den eksperimentielt? Kør programmet for forskellige størrelser og mål køretiden (manuelt eller automatisk). Fordoblingsteknik: Kig på hvilken faktor køretiden vokser med når man fordobler størrelsen af input. Tid vokser med en faktor ~ når input vokser med faktor. Passer med kvadratisk køretid: T(n) = cn T(n) = c(n) = c n = cn T(n)/T(n) = n tid (sekunder) ratio 000 0-0000 0. - 0000 0. 0000.. 0000 9. 0000. 0000? Opsummering Teoretisk analyse af algoritmer Køretid Pladsforbrug Asymptotisk notation O, Θ og Ω-notation. Eksperimentiel analyse af algoritmer Introduktion til datastrukturer Philip Bille
Plan Datastrukturer Stakke og køer Hægtede lister Dynamiske tabeller Datastrukturer Datastrukturer Datastruktur: Metode til at organise data så det kan søges i/tilgås/ manipuleres effektivt. Mål: kompakt og hurtig. Dynamisk vs. statisk datastruktur. Abstrakt vs. konkret datastruktur. Stakke og køer
Stak Implementation med tabel Vedligehold en dynamisk sekvens X af elementer under følgende operationer. Push(x): tilføj et nyt element x til X Pop(): fjern og returner det seneste tilføjede element i X. isempty(): returner sand hvis X ikke indeholder nogle elementer. Implementer en stak med maksimalt N elementer. Datastruktur: Tabel X[..N] Position top i X. Operationer: Push(x): Tilføj x på X[top+], sæt top = top + Pop(): returner X[top], sæt top = top - isempty(): returner sand hvis og kun hvis top =. Tjek for overløb og underløb i Push og Pop. Analyse Kø Hvor hurtigt kører Push, Pop, isempty? Push, Pop, isempty bruger Θ() tid. Hvor meget plads bruger vi? Θ(N) Vedligehold en dynamisk sekvens X af elementer under følgende operationer. Enqueue(x): tilføj et nyt element x til X Dequeue(): fjern og returner det tidligst tilføjede element i X. isempty(): returner sand hvis X ikke indeholder nogle elementer. Den dårlige nyhed: Vi skal kende den maksimale størrelse af stakken fra start. Vi spilder plads når antal elementer i stakken er < N.
Implementation med tabel Implementer en kø med maksimalt N elementer. Datastruktur: Tabel X[..N] Positioner head (tidligst indsatte element) og tail (næste ledige element) i X og tæller count (antal elementer i kø). Operationer: Enqueue(x): Tilføj x på X[tail], opdater count og tail cyclisk. Dequeue(): returner X[head], opdater count og head cyclisk. count= count= count= dequeue() dequeue() head tail head tail head tail count= count= count= enqueue() enqueue(9) 9 dequeue() 9 tail head tail head tail head isempty(): returner sand hvis og kun hvis count = 0. Tjek for overløb og underløb i Dequeue og Enqueue. Analyse Stakke og køer Hvor hurtigt kører Dequeue, Enqueue, isempty? Dequeue, Enqueue, isempty bruger Θ() tid. Hvor meget plads bruger vi? Θ(N) Den dårlige nyhed: Vi skal kende den maksimale størrelse af køen fra start. Vi spilder plads når antal elementer i køen er < N. Stak implementeret med tabel Køretid: Push, Pop, isempty i Θ() tid. Pladsforbrug: Θ(N) Kø implementeret med tabel Køretid: Enqueue, Dequeue, isempty i Θ() tid. Pladsforbrug: Θ(N) Kan vi komme ned på lineær plads med samme tid?
Hægtede lister Datastruktur til at vedligeholde en sekvens af elementer i lineær plads. Rækkefølge af elementer bestemt af referencer/pegere kaldet hægter. Effektiv at indsætte og fjerne elementer eller delsekvenser af elementer. Hægtede lister Dobbelt-hægtede eller enkelt-hægtede. head null Dobbelt-hægtede lister i Java Hvordan implementerer man dobbelt-hægtede lister i Java? head null null
class Node { int key; Node next; Node prev; } Node head = new Node(); Node b = new Node(); Node c = new Node(); head.key = ; b.key = ; c.key = ; head.prev = null; head.next = b; b.prev = head; b.next = c; c.prev = b; c.next = null; head null head null null b b null null c c null null null Node Insert(Node head, Node x) { x.prev = null; x.next = head; head.prev = x; return x; } Node Search(Node head, int value) { Node x = head; while (x = null) { if (x.key == value) return x; x = x.next; } return null; } Node Delete(Node head, Node x) { if (x.prev = null) x.prev.next = x.next; else head = x.next; if (x.next = null) x.next.prev = x.prev; return head; } Analyse Stak og kø implementation med hægtede lister Hvor hurtigt kører Search, Insert og Delete på liste af længde n? Θ(n) for Search Θ() for Insert og Delete Hvor meget plads bruger en hægtet liste af størrelse n? Θ(n) Hvordan kan man implementere stakke og køer med hægtede lister? Stak Push Pop isempty Kø Enqueue Dequeue isempty
Stakke og køer Hægtede lister Stak implementeret med hægtet liste Køretid: Push, Pop, isempty i Θ() tid. Pladsforbrug: Θ(n) Fleksibel datastruktur til at vedligeholde en sekvens af elementer i lineær plads. Eksempel på hægtet datastruktur. Findes også cykliske lister, træer, grafer, Kø implementeret med hægtet liste Køretid: Enqueue, Dequeue, isempty i Θ() tid. Pladsforbrug: Θ(n) root null null null 0 null null null null Dynamiske tabeller null null
Stak med dynamisk tabel Første forsøg Kan vi implementere en stak effektivt med tabel(ler)? Behøver vi fastsætte en øvre grænse på antallet af elementer? Kan vi komme ned på lineær plads og konstant tid? Mål: Vi vil kun bruge Θ(n) plads for stak med n elementer Ignorer Pop og isempty indtil videre. Datastruktur: Tabel X[..n] Operationer: Push(x): Opret ny tabel af størrelse n+. Flyt alle elementer til ny tabel. Slet gammel tabel. Analyse Andet forsøg Hvor hurtigt kører det? n Push-operationer tager + + + + n = Θ(n ) tid. Plads: Θ(n) plads. Ide: Undgå at bygge en tabel og flytte elementer for ofte. Fordobling: Start med tabel af størrelse. Hvis tabel er fuld (antallet af elementer i stak er lig tabellens størrelse). Opret ny tabel af dobbelt størrelse. Flyt elementer over i ny tabel. Slet gammel tabel.
Analyse Stak Hvor hurtigt kører det? n Push-operationer tager + + + + + n/ + n < n = Θ(n) tid. Plads: Θ(n) plads. Stak implementeret med dynamisk tabel Køretid: n Push operationer tager Θ(n) tid. Pladsforbrug: Θ(n) Muligt at opnå n Push, pop og isempty operationer i Θ(n) tid. Tilsvarende resultat for køer Køretiden er amortiseret Θ() per operation. Med snedige tricks: Muligt at deamortisere løsning og opnå Θ() værstefaldskøretid per operation. Opsummering Datastrukturer Stakke og køer Hægtede lister Dynamiske tabeller Prioritetskøer og hobe Philip Bille
Plan Prioritetskøer Træer Hobe Repræsentation Prioritetskøoperationer Prioritetskøer Konstruktion af hob Hobsortering Prioritetskø Anvendelser Vedligehold en dynamisk mængde S af elementer. Hver element x er tilknyttet en nøgle x.key. Insert(x): sæt S = S cup {x}. Max(): returner element med største nøgle. Extract-Max(): fjern og returner element med største nøgle. Increase-Key(x, k): sæt x.key = k (vi antager k er større end x.key). Hvad kan vi bruge en prioritetskø til? Skedulering Korteste veje i grafer (Dijkstras algoritme + venner) Mindste udspændende træer i grafer (Prims algoritme) Kompression (Huffmans algoritme)
Implementation Hvordan kan vi implementere en prioritetkø med nuværende teknikker? Med hægtet liste: O(n) for Insert, Max, Extract-Max og Increase-Key Med sorteret hægtet liste: O() for Max, Extract-Max Træer O(n) for Insert og Increase-Key. Kan vi gøre det betydeligt bedre? Kræver nye teknikker Rodfæstet træ T. Består af knuder og kanter. Børn, forælder, efterkommer, forfader, blade, interne knuder. Acyklisk sammenhængende graf. Lad v være en knude i T. dybden af v = længden af sti fra v til roden. højden af v = længden af længste sti fra v til en bladefterkommer. dybden af T = højden af T = længden af længste sti fra rod til et blad.
Binært træ = alle knuder har børn, kaldet venstre barn og højre barn. Komplet binært træ = alle interne knuder netop børn. Næsten komplet binært træ = komplet binært træ hvor 0 eller flere blade er fjernet fra højre mod venstre. Hvad er sammenhæng mellem antallet af knuder og højden af (næsten) komplet binært træ? 0 k 0 k k 9 n = antal knuder, h = højden. Antal blade = h Antal interne knuder = + + + + h- = h - n = h + h - = h+ - h = Θ(log n) (gælder også for næsten komplet binært træ) En hob (heap) er et næsten komplet binært træ så hver knude indeholder et element hver knudes nøgle et højst ligeså stor som dens forælders (hob-orden) Kaldes en max-hob. Tilsvarende kan man definere min-hob.
Repræsentation af hobe 0 Hvordan kan vi repræsentere en hob? Vi har brug for effektivt at kunne navigere mellem børn og forælder. 0 9 root null 0 null 0 null null null null null null null null 9 null null null null 0 0 9 9 0 0 0 9 Prioritetskøoperationer Hvordan kan vi implementere prioritetskøoperationerne? Insert(x): sæt S = S {x}. Max(): returner element med største nøgle. Extract-Max(): fjern og returner element med største nøgle. Increase-Key(x, k): sæt x.key = k (vi antager k er større end x.key). 9 0 0 0 9 Tabel H[..n]. H[] er rod, H[n] er blad længst til højre. Knude i har venstre barn på i, højre barn på i+ og forælder på i/
Insert(x): Indsæt x på næste ledige plads i tabel. Bobl op. Max(): Returner toppen af hob i A[] Extract-Max() r = top af hob. Flyt blad længst til højre til top af hob. Bobl ned (Max-Heapify) Analyse Køretid: Insert, Extract-Max, Increase-Key i O(log n) tid Max i O() tid. Pladsforbrug: O(n) plads. Eksempel på implicit datastruktur. Returner r. Increase-Key(x,k) Sæt x.key = k Bobl op. Konstruktion af hob Lav A[..n] være en tabel af heltal. Hvordan kan vi effektivt bygge en hob ud af tallene i A? (præprocessering) Konstruktion af hob
Første forsøg Andet forsøg Sæt alle elementer i A ind i hoben med n Insert operationer. Tid: Θ(n log n) Bygger hoben "oppefra og ned". Kan vi gøre det bedre? Opfat A som næsten komplet binært træ og Etabler hoborden nedefra og op for alle knuder Blade er allerede hobe af størrelse. For hver intern knude, bobl ned. Hvor hurtigt kører det? Konstruktion af hob Givet en tabel A[..n] kan vi bygge en hob i Θ(n) tid. Bruger kun O() ekstra plads. For hver knude af højde h: O(h) tid. ~ n/ knuder af højde, n/ knuder af højde, n/ knuder af højde,..., knude af højde h. n/ + n/ + n/ +... + h = O(n) O(n) tid
Hobsortering Lad A[..n] være en tabel. Hobsortering: Byg hob af A. Hobsortering Lav n Extract-Max. Indsæt resultater sidst i tabel i stedet for at slette. Analyse. Byg en hob i Θ(n) tid n Extract-Max i Θ(nlog n) tid. i alt Θ(nlog n) tid. Hobsortering Opsummering Givet en tabel A[..n] kan vi sortere i Θ(n log n) tid. Bruger kun O() ekstra plads. Ækvivalens af sortering og prioritetskøer. Prioritetskøer Træer Hobe Repræsentation Prioritetskøoperationer Konstruktion af hob Hobsortering
Plan Uorienterede grafer Anvendelse og modellering med grafer Introduktion til grafer Philip Bille Søgning i grafer Dybdeførst søgning Sammenhængskomponenter Breddeførst søgning Korteste vej Todelte grafer Uorienterede grafer 9 Uorienterede grafer 0 (Uorienterede) grafer består af knuder forbundet med kanter. Hvorfor studere grafer? Modellerer naturligt mange problemer i mange forskellige områder. Tusindvis af praktiske anvendelser. Hundredevis af kendte grafalgoritmer.
"Visualizing friendships", Paul Butler Tube map Chesham 9 Chalfont & Latimer Amersham http://en.wikipedia.org/wiki/opte_project Watford Rickmansworth Uxbridge Ruislip Manor Ickenham Harrow & Wealdstone Harrowon-the-Hill West Harrow South Harrow South Ruislip B Edgware Stanmore Kenton Queensbury Preston Road Kingsbury North Wembley Neasden Wembley Park Kensal Rise Willesden Junction Queen s Park Kilburn High Road Kilburn Park C Maida Vale Warwick Avenue Westbourne Park Park Royal East Acton Ealing Broadway West Acton North Acton Acton Central Ealing Common South Acton D South Ealing Boston Manor Acton Town Chiswick Park Shepherd s Bush White City Wood Lane Shepherd s Bush Market West Kensington Kew Gardens Hounslow Central Richmond Heathrow Terminals,, Heathrow Terminal Baker Street Bond Street Gloucester Road Cannon Street Mansion House Charing Cross Blackfriars Imperial Wharf East Putney Vauxhall Clapham Junction Wandsworth Road Wimbledon Tooting Bec Tooting Broadway Colliers Wood South Wimbledon MAYOR OF LONDON Rotherhithe Morden Bermondsey Heron Quays South Quay East Ham West Ham Devons Road Star Lane Langdon Park Canning Town All Saints Blackwall Poplar C Upton Park Plaistow Royal Victoria East India Custom House for ExCeL Emirates Royal Docks Prince Regent Royal Albert West Silvertown D Beckton Park Cyprus North Greenwich Emirates Greenwich Peninsula Pontoon Dock Gallions Reach London City Airport Beckton King George V Queens Road Peckham Peckham Rye Stockwell New Cross Greenwich Brockley Woolwich Arsenal E Elverson Road Lewisham Hammersmith & City Jubilee Metropolitan Sydenham Northern Penge West Piccadilly Anerley Crystal Palace London metro, London Transport F Norwood Junction West Croydon Central Circle Forest Hill Brixton Bakerloo District District open weekends, public holidays and some Olympia events Deptford Bridge Honor Oak Park Denmark Hill Cutty Sark for Maritime Greenwich New Cross Gate Bank Waterloo & City line open between Bank and Waterloo 0-000 Mondays to Fridays and 00-000 Saturdays. Between Waterloo and Bank 0-000 Mondays to Fridays and 000-000 Saturdays. Closed Sundays and Public Holidays. --------------------------------------------------------------------------------Camden Town Sunday 00-0 open for interchange and exit only. --------------------------------------------------------------------------------Canary Wharf Step-free interchange between Underground, Canary Wharf DLR and Heron Quays DLR stations at street level. --------------------------------------------------------------------------------Cannon Street Open until 00 Mondays to Fridays and 00-90 Saturdays. Closed Sundays. --------------------------------------------------------------------------------Embankment Bakerloo and Northern line trains will not stop at this station from early January 0 until early November 0. --------------------------------------------------------------------------------Emirates Greenwich Peninsula and Emirates Royal Docks Special fares apply. Open 000-000 Mondays to Fridays, 000-000 Saturdays, 0900-000 Sundays and 000-000 Public Holidays. Opening hours are extended by one hour in the evening after April 0 and may be extended on certain events days. Please check close to the time of travel. --------------------------------------------------------------------------------Heron Quays Step-free interchange between Heron Quays and Canary Wharf Underground station at street level. --------------------------------------------------------------------------------Hounslow West Step-free access for manual wheelchairs only. --------------------------------------------------------------------------------Kilburn No step-free access from late January 0 until mid May 0. --------------------------------------------------------------------------------Stanmore Step-free access via a steep ramp. --------------------------------------------------------------------------------Turnham Green Served by Piccadilly line trains until 00 Mondays to Saturdays, 0 Sundays and after 0 every evening. At other times use District line. --------------------------------------------------------------------------------Waterloo Waterloo & City line open between Bank and Waterloo 0-000 Mondays to Fridays and 00-000 Saturdays. Between Waterloo and Bank 0-000 Mondays to Fridays and 000-000 Saturdays. Closed Sundays and Public Holidays. No step-free access from late January 0 until late July 0. --------------------------------------------------------------------------------West India Quay Not served by DLR trains from Bank towards Lewisham before 00 on Mondays to Fridays. --------------------------------------------------------------------------------- Key to lines Island Gardens Borough Kennington Upney Barking Canary Wharf Canada Water Crossharbour Elephant & Castle Oval Dagenham Heathway Abbey Road Bromleyby-Bow West India Quay Wapping Mudchute Lambeth North Clapham North F Westferry Limehouse Tower Gateway Surrey Quays Clapham Common Balham Tower Hill Southwark Stepney Green Whitechapel Shadwell River Thames London Bridge Waterloo Pimlico Pudding Mill Lane Elm Park Becontree Woodgrange Park Bow Road Aldgate Fenchurch Street Embankment Clapham South Monument Aldgate East Wanstead Park Mile End B Hornchurch Dagenham East Stratford Bow Church Temple Westminster Clapham High Street Transport for London Bank Upminster Upminster Bridge Leyton Stratford High Street Bethnal Green St. Paul s Holborn Gants Hill Leytonstone High Road Hackney Wick Shoreditch High Street Moorgate Chancery Lane Leicester Square St. James s Park Hoxton Liverpool Street Barbican Piccadilly Circus Victoria Canonbury Dalston Junction Fairlop Barkingside Newbury Park Wanstead Stratford International Homerton Farringdon Russell Square Leytonstone Leyton Midland Road A Redbridge Walthamstow Central Hackney Central Old Street Euston Square Snaresbrook Walthamstow Queen s Road Haggerston Covent Garden Putney Bridge Wimbledon Park Caledonian Road & Barnsbury Tottenham Hale Dalston Kingsland King s Cross St. Pancras Tottenham Court Road Sloane Square South Kensington South Woodford Grange Hill Chigwell Hainault Blackhorse Road Euston Green Park Southfields Mornington Crescent Goodge Street Marble Arch Hyde Park Corner Finsbury Park Highbury & Islington Angel Oxford Circus Fulham Broadway Parsons Green Arsenal Holloway Road Kentish Town Camden Road Camden Town Warren Street Knightsbridge Earl s Court Chalk Farm Great Portland Street West Brompton Hounslow East Hatton Cross Heathrow Terminal Queensway Seven Sisters South Tottenham Tufnell Park Regent s Park Lancaster Gate High Street Kensington Barons Court Hammersmith Turnham Stamford Ravenscourt Brook Park Green Gunnersbury E Holland Park Harringay Green Lanes Manor House Upper Holloway Kentish Town West Bayswater Notting Hill Gate Kensington (Olympia) Goldhawk Road Osterley Hounslow West St. John s Wood Edgware Road Ladbroke Grove Latimer Road North Ealing Northfields Swiss Cottage Edgware Marylebone Road Royal Oak Hanger Lane Paddington Finchley Road South Hampstead Woodford Turnpike Lane Caledonian Road West Hampstead Brondesbury Kensal Green Alperton Roding Valley Crouch Hill Archway Gospel Oak Hampstead Heath Belsize Park Kilburn Brondesbury Park Greenford Perivale Hampstead Finchley Road & Frognal Willesden Green Harlesden Finchley Central Highgate Dollis Hill Stonebridge Park Check before you travel Buckhurst Hill Arnos Grove Bounds Green Wood Green Golders Green Wembley Central Sudbury Hill Loughton Southgate West Finchley East Finchley Brent Cross 9 Debden Oakwood Woodside Park Mill Hill East Colindale Hendon Central South Kenton Northolt Sudbury Town Burnt Oak Canons Park Northwick Park Epping Theydon Bois Hatch End North Harrow Rayners Lane Cockfosters Totteridge & Whetstone Headstone Lane Pinner Eastcote Ruislip Gardens High Barnet Carpenders Park Northwood Northwood Hills Ruislip Bushey Moor Park West Ruislip Hillingdon Watford Junction Watford High Street Croxley Chorleywood A Special fares apply Victoria Waterloo & City DLR London Overground This diagram is an evolution of the original design conceived in 9 by Harry Beck Correct at time of going to print, December 0 Emirates Air Line 9 Protein-protein interaktionsnetværk, Jeong et al, Nature Review Genetics
graf knuder kanter kommunikation computer kabel transport vejkryds vej 9 0 V = {,,,,,,,,9,0,} E = {(,), (,), (,), (,), (,), (,), (,), (,), (9,0), (0, )} n = m = 0 transport lufthavn fly spil position lovligt træk neuralt netværk neuron synapse finansnetværk valuta, aktier transaktioner kredsløb logiske porte forbindelse fødekæde dyrearter rovdyr-byttedyr molekyle atom bindinger Uorienteret graf G = (V,E): V = Mængde af knuder (vertices/nodes). E = kanter (edges) mellem par af knuder. n = V og m = E Sti/vej (path): sekvenser af knuder forbundet af kanter. Kreds (cycle): sti hvis start- og slutknude er ens. deg(v) = grad af knude v = #naboer af v = #kanter incidente med v. Vej: findes der en sti mellem s og t? 9 0 V = {,,,,,,,,9,0,} E = {(,), (,), (,), (,), (,), (,), (,), (,), (9,0), (0, )} n = m = 0 Korteste vej: hvad er den korteste vej mellem s og t? Længste vej: hvad er den længste vej mellem s og t? Kreds: er der en kreds i grafen? Eulertur: er der en kreds, der benytter hver kant netop en gang? Lemma: v V deg(v) = m. Bevis: Hvor mange gange tælles en kant med i sum? Hamiltontur: er der en kreds, der benytter hver knude netop en gang? Sammenhæng: er det muligt at forbinde alle knuder med en sti? Mindste udspændende træ: hvad er den bedste måde at forbinde alle knuder på? Tosammenhæng: er der en knude hvis fjernelse gør grafen usammenhængende? Planaritet: er det muligt at tegne grafen i planen uden kanter der krydser? Grafisomorfi: repræsentere to mængde af knuder og kanter samme graf?
Repræsentationer Hvordan kan man repræsentere en graf? Incidensmatrix Incidensliste Repræsentation af grafer Analyse Incidensmatrix: O(n ) plads. O() tid for at afgøre om par af knuder u og v er naboer. Incidensliste: O(n+m) plads. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 null null null null null null O(deg(u)) = O(n) tid for at afgøre om par af knuder u og v er naboer.
Søgning i grafer Hvordan kan vi udfra en knude s systematisk udforske (besøge alle knuder og kanter) i en graf? Dybdeførst søgning (depth-first search) Søgning i grafer Breddeførst søgning (breadth-first search) Dybdeførst søgning (DFS) Ide: Udforsk ud fra s i en retning indtil vi når en "blindgyde". Dybdeførst søgning Gå tilbage til sidste knude hvor der var flere uudforskede kanter og fortsæt på samme måde. Algoritme: Til at starte med er alle knuder umarkerede. Besøg knude s. Når vi besøger knude v Marker v Besøg alle umarkerede naboer af v rekursivt.
Analyse Dybdeførst søgning Hvor hurtigt kører DFS (på incidenslisterepræsentationen)? Vi kan udforske en graf med dybdeførst søgning i O(n + m) tid. Markering af knuder? O() tid pr knude. Hvor mange gange besøger DFS en knude v? Højst en gang. Hvor meget tid bruger DFS på v? O(deg(v)) tid. For alle knuder deg(v) = m = O(m) tid. Total køretid: O(n + m) 9 0 Sammenhængskomponenter Givet knude s, hvordan kan finde alle knuder i sammenhængskomponenten K(s) for s? Sammenhængskomponent for s = alle knuder der har en sti til s.
Farveudfyldning (flood fill). Skift farve til blå på sammenhængende område af grønne pixels Knude = pixel Kant = nabopixel med samme farve Sammenhængende område = sammenhængskomponent af grønne pixel. Farveudfyldning (flood fill). Skift farve til blå på sammenhængende område af grønne pixels Knude = pixel Kant = nabopixel med samme farve Sammenhængende område = sammenhængskomponent af grønne pixel. 9 9 0 0 Vi kan bruge DFS fra s til at finde K(s). DFS fra s: Markerer alle de knuder der har en sti til s = alle knuder i K(s). Køretid: O(ns + ms) (ns = #antal knuder i K(s), ms = #antal kanter i K(s)) Givet to knuder s og t er der en sti mellem s og t? Køretid: O(ns + ms). G er sammenhængende? Køretid: O(n + m). Find alle sammenhængskomponenter af G. Køretid: O(n + m).
Breddeførst søgning (BFS) Ide: Udforsk udfra s i alle mulige retninger, et lag knuder ad gangen. Algoritme: Vedligehold en kø og markering af knuder + afstand til s. Breddeførst søgning Start med Enqueue(s) i kø. Gentag indtil kø er tom: Dequeue knude v fra kø. For alle umarkede naboer u til v: Marker u og sæt afstand. Enqueue(u). Korteste veje Analyse Hvorfor beregner BFS længden af den korteste vej fra s til alle andre knuder? Intuition: Kig på lagene. L0 = {s} L = alle naboer til L0. L = alle naboer til L der ikke er naboer til L0 L = alle naboer til L der ikke er naboer til L0 og L. Li = alle naboer til Li- der ikke er naboer til Lj for j < i- = alle knuder med afstand i til s. Hvor hurtigt kører BFS? Enqueue, Dequeue, marker en knude? O() tid. Hvor mange gange besøger BFS en knude v? Højst en gang. Hvor meget tid bruger BFS på v? O(deg(v)) tid. For alle knuder deg(v) = m = O(m) tid. Total køretid: O(n + m)
Breddeførst søgning Vi kan udforske en graf med breddeførst søgning i O(n + m) tid. Todelte grafer En graf G er todelt (bipartite) hvis og kun hvis alle knuder kan farves røde eller blå således at alle kanter har et rødt og et blåt endepunkt. Er grafen todelt? Alternativt: En graf G er todelt hvis og kun hvis knuder kan deles i to mængder V og V så alle kanter går mellem V og V. Anvendelser i kodning, skedulering, matching, Mange grafproblemer er nemmere på todelte grafer.
Tilfælde Tilfælde Lemma: En graf er todelt hvis og kun hvis den ikke indeholder kredse af ulige længde. Hvis todelt så starter og slutter alle kredse i samme side. Hvis der er kreds af ulige længde kan vi ikke farve den. Lemma: Lad G være graf med lag L0, L,, Lk produceret af BFS. Præcis en af følgende holder:. Ingen kant forbinder knuder i samme lag G er todelt.. En kant forbinder knuder i samme lag G indeholder en ulige kreds G er ikke todelt. Todelte grafer Opsummering Vi kan afgøre om en graf er todelt i O(n + m) tid. Uorienterede grafer Anvendelse og modellering med grafer Søgning i grafer Dybdeførst søgning Sammenhængskomponenter Breddeførst søgning Korteste vej Todelte grafer
Orienterede grafer Orienterede grafer Introduktion Repræsentation Søgning Topologisk sortering og DAGs Stærke sammenhængskomponenter Implicitte grafer Introduktion Repræsentation Søgning Topologisk sortering og DAGs Stærke sammenhængskomponenter Implicitte grafer Philip Bille Orienterede grafer Orienterede grafer Orienteret graf. Mængde af knuder forbundet parvis med orienterede kanter. deg + () =, deg - () = Lemma. v V deg - (v) = v V deg + (v) = m. Bevis. Hver kant har netop en startknude og slutknude. sti fra til 9 9 0 kreds 0
Google Maps /0/ : Vejnetværk Spildopsamling (garbage collection) Knude = vejkryds, kant = ensrettet vej. Knude = objekt, kant = peger/reference. rødder Hvilke objekter kan vi nå fra en rod? Map data 0 Google 0 m WWW Automater og regulære udtryk Knude = hjemmeside, kant = hyperlink. Knude = tilstand, kant = tilstandsovergang. Webcrawling PageRank https://www.google.dk/maps/@.,.,z Accepterer automaten aab = findes sti fra til 0 der matcher aab? Page of Regulære udtryk kan repræsenteres som automat. a a R = a (a ) (b c) http://computationalculture.net/article/what_is_in_pagerank b c 0 9
Afhængigheder Afhængigheder Knude = emner, kant = afhængighed. Er der nogle cykliske afhængigheder? Hvordan kan vi finde en rækkefølge emnerne så vi undgår afhængigheder? tabeller flettesortering hægtede lister stakke køer flettesortering indsættelsessortering stakke grafer stærke sammenhængkomponenter ordbøger indsættelsessortering hob tabeller ordbøger køer uorienterede grafer orienterede grafer foren og find grafer uorienterede grafer binær søgning binære søgetræer binær søgning hægtede lister BFS/DFS topologisk sortering MST orienterede grafer binære søgetræer foren og find MST korteste veje BFS/DFS topologisk sortering korteste veje hob Dijkstras algoritme Dijkstras algoritme stærke sammenhængkomponenter Problemer på orienterede grafer graf knuder kanter internet hjemmeside hyperlink transport vejkryds ensrettet vej skedulering job precedens relation infektionssygdom person infektion citation artikel citation Sti. Er der en sti fra s til t? Korteste sti. Hvad er den korteste sti fra s til t. Orienteret acyclisk graf. Findes der kredse i grafen? Topologisk sortering. Kan vi ordne knuder i en sekvens så alle kanter peger samme vej? Stærk sammenhængskomponent. Er der en vej mellem alle par af knuder? Transitiv afslutning. For hvilke knuder v og w er der en sti fra v til w? objekt graf objekter pegere/referencer objekt hieraki klasse nedarver fra kontrol-flow kode hop
Orienterede grafer Introduktion Repræsentation Søgning Topologisk sortering og DAGs Stærke sammenhængskomponenter Implicitte grafer Incidensmatrix Incidensmatrix. D n n tabel. Plads. O(n ) Tid for afgøre om v peger på u. O() 9 0 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Incidensliste Repræsentation Incidensliste. Tabel af hægtede lister. Plads. O(n + m) Tid for afgøre om v peger på u. O(deg + (v)) I praksis. De fleste grafer i virkeligheden er tynde brug incidenslister. 9 0 9 0 0 0 9 0 repræsentation plads kant fra v til u? incidensmatrix O(n O() incidensliste O(n + m) O(deg 0
Orienterede grafer Introduktion Repræsentation Søgning Topologisk sortering og DAGs Stærke sammenhængskomponenter Implicitte grafer DFS(s) DFS-visit(s) DFS-visit(v) marker v for alle umarkerede knuder w som v peger på DFS-visit(w) π[w] = v BFS(s) Enqueue(s) marker s d[s] = 0 gentag indtil kø er tom v = Dequeue() for alle umarkede w som v peger på marker w d[w] = d[v] + π[w] = v Enqueue(w) Søgning i grafer DFS og BFS i O(n + m) tid på orienterede grafer. Orienterede grafer Introduktion Repræsentation Søgning Topologisk sortering og DAGs Stærke sammenhængskomponenter Implicitte grafer
Topologisk sortering og DAGs DAGs og topologisk sortering DAG. Orienteret acyclisk graf (directed acyclic graph). Graf uden kredse. Topologisk sortering. Ordning af knuder v, v,, vn fra venstre til højre således at alle kanter peger mod højre. Problemer. Er G en DAG? Hvordan beregner vi en topologisk sortering? Mål. Vise G er en DAG G har en topologisk sortering + find algoritme til at løse begge problemer. Lemma. G har en topologisk sortering G er en DAG. Bevis. Modbevis. v i v j Antag G har topologisk sortering v, v,, vn og ikke er en DAG. G indeholder kreds K. Kig på knude vi i K som er længst til venstre i sortering og knude vj lige før (vj, vi) er kant i K og dermed i G. Men vi er før vj i rækkefølge v, v,, vn er ikke en topologisk sortering. DAGs og topologisk sortering DAGs og topologisk sortering Opgave. Givet en DAG, find på en strategi til at beregne en topologisk sortering. Lemma. G er en DAG G har en knude med indgrad 0. Bevis. Modbevis. Antag G er en DAG og alle knuder har indgrad. Vælg knude v og følg kanter baglæns fra v. Efter n+ skridt må der være mindst knude u vi har besøgt gange. u + de knuder mellem første og anden gang vi besøger u udgør kreds.
DAGs og topologisk sortering Algoritme Lemma. G er en DAG G har topologisk sortering. Bevis. Induktion over n Basis n =. Induktionsskridt n >. Find knude med indgrad 0. G - {v} er en DAG G - {v} har en topologisk sortering. Placer v længst til venstre efterfulgt af den topologiske sortering af G - {v}. Giver topologisk sortering af G da v ikke har nogen indgående kanter. Induktionsbevis som algoritme. Korrekthed. Følger af induktionsbevis. TopSort(G) if G = ({v}, ) print v else find v så deg - (v) = 0 print v TopSort(G - {v}) Implementation Mål. Implementer algoritmen effektivt på incidenslisterepræsentation TopSort(G) if G = ({v}, ) print v else find v så deg - (v) = 0 print v TopSort(G - {v})
Implementation Implementation Løsning. Konstruer omvendt graf G R. Linæer søgning i incidensliste for G R efter knude med indgrad 0 i hvert skridt. Tid per knude. Find knude v med indgrad 0: O(n). Fjern kanter ud af v: O(deg + (v)) TopSort(G) if G = ({v}, ) print v else find v så deg - (v) = 0 print v TopSort(G - {v}) Samlet tid for n knuder. O(n + v V deg + (v)) = O(n + m) = O(n ). Løsning. Vedligehold indgrad af hver knude i incidensliste + hægtet liste af alle knuder med indgrad 0. Initialisering. O(n+m) Tid per knude. Find knude v med indgrad 0: O(). Fjern kanter ud af v: O(deg + (v)) TopSort(G) if G = ({v}, ) print v else find v så deg - (v) = 0 print v TopSort(G - {v}) Samlet tid for n knuder. O(n + v V deg + (v)) = O(n + m). 0-deg deg tabel 0 0 0 Topologisk sortering og DAGs Topologisk sortering med DFS Lemma. G er en DAG G har en topologisk sortering. Theorem. Vi kan afgøre om G er DAG og hvis den er så finde en topologisk sortering i O(n + m) tid. Topologisk sortering med DFS. Ide. Kør DFS på G. Ved slutning af rekursivt kald til knude v læg v på stak. Udskriv stak. Tid. O(n + m) Intuition. Finder rekursivt knuder med udgrad 0.
Stærke sammenhængskomponenter Orienterede grafer Introduktion Repræsentation Søgning Topologisk sortering og DAGs Stærke sammenhængskomponenter Implicitte grafer Def. v og u er stærk sammenhængende (strongly connected) hvis der er sti fra v til u og fra u til v. Def. Et stærk sammenhængskomponent (strongly connected component) er en maksimal delmængde af stærk sammenhængende knuder. 9 0 Stærke sammenhængskomponenter med DFS Stærke sammenhængskomponenter med DFS Stærke sammenhængskomponenter med DFS. Ide. Kør DFS på omvendt graf G R. Kør DFS på G ifht. rækkefølge fra første DFS. Hver rekursiv søgning finder et stærkt sammenhængskomponent. Intuition? Korrekthed. Se kap. i CLRS. Tid. O(n + m) Theorem. Vi kan finde alle stærke sammenhængskomponenter i O(n + m) tid.
Implicit graf Orienterede grafer Introduktion Repræsentation Søgning Topologisk sortering og DAGs Stærke sammenhængskomponenter Implicitte grafer Implicit graf. Uorienteret/orienteret graf G repræsenteret implicit. Implicit repræsentation. Startknude s. Algoritme til at generere naboer af en knude. Bruges i spil, kunstig intelligens, etc. Rubiks terning Rubiks terning Rubiks terning n+m =..00..9..000 ~ trillioner. Hvad er det optimale antal træk man skal bruge på at "løse" en terning ligegyldigt hvor man starter? år nedre grænse øvre grænse 9 990 99 9 99 99 9 99 0 9 00 0 00 0 00 0 00 0 00 0 00 0 00 0 0 www.cube0.org
Orienterede grafer Introduktion Repræsentation Søgning Topologisk sortering og DAGs Stærke sammenhængskomponenter Implicitte grafer
Mindste udspændende træ Mindste udspændende træ Introduktion Repræsentation af vægtede grafer Egenskaber for mindste udspændende træer Prims algoritme Kruskals algoritme Introduktion Repræsentation af vægtede grafer Egenskaber for mindste udspændende træer Prims algoritme Kruskals algoritme Philip Bille Introduktion Vægtede grafer. Vægt w(e) på hver kant e i G. Udspændende træ. Delgraf T af G over alle knuder der er sammenhængende og acyklisk. Mindste udspændende træ (MST). Udspændende træ af minimal samlet vægt. Introduktion Vægtede grafer. Vægt w(e) på hver kant e i G. Udspændende træ. Delgraf T af G over alle knuder der er sammenhængende og acyklisk. Mindste udspændende træ (MST). Udspændende træ af minimal samlet vægt. 9 9 0 0 Graf G Ikke sammenhængende
Introduktion Vægtede grafer. Vægt w(e) på hver kant e i G. Udspændende træ. Delgraf T af G over alle knuder der er sammenhængende og acyklisk. Mindste udspændende træ (MST). Udspændende træ af minimal samlet vægt. Introduktion Vægtede grafer. Vægt w(e) på hver kant e i G. Udspændende træ. Delgraf T af G over alle knuder der er sammenhængende og acyklisk. Mindste udspændende træ (MST). Udspændende træ af minimal samlet vægt. 9 9 0 0 Sammenhængende og cyklisk Sammenhængende og acyklisk = udspændende træ T Vægt af T = + + + + 9 + + = Introduktion Vægtede grafer. Vægt w(e) på hver kant e i G. Udspændende træ. Delgraf T af G over alle knuder der er sammenhængende og acyklisk. Mindste udspændende træ (MST). Udspændende træ af minimal samlet vægt. 9 Anvendelser Netværk design. Computer, vej, telefon, elektrisk, kredsløb, kabel tv, hydralisk, Approksimationsalgoritmer. Handelsrejsendes problem, steiner træer. Andre anvendelser. Meteorologi, kosmologi, biomedicinsk analyse, kodning, billedanalyse, Se f. eks. http://www.ics.uci.edu/~eppstein/gina/mst 0 Mindste udspændende træ T Vægt af T = + + + + + 9 + = 0
Repræsentation af vægtede grafer Incidensmatrix og incidensliste. Mindste udspændende træ Tilsvarende for orienterede grafer. 0 0 0 0 0 0 0 0 0 0 Introduktion Repræsentation af vægtede grafer Egenskaber for mindste udspændende træer Prims algoritme Kruskals algoritme 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Egenskaber for MST Simplificerende antagelse. Mindste udspændende træ Alle kantvægte i G er forskellige. G er sammenhængende MST eksisterer og er unik. Introduktion Repræsentation af vægtede grafer Egenskaber for mindste udspændende træer Prims algoritme Kruskals algoritme
Snitegenskab Def. Et snit er en opdeling af knuderne i to (ikke-tomme) mængder. Def. En snitkant i et snit er en kant med et endepunkt i hver side af snittet. Snitegenskab. For et vilkårligt snit, er den letteste snitkant med i MST. Snitegenskab Def. Et snit er en opdeling af knuderne i to (ikke-tomme) mængder. Def. En snitkant i et snit er en kant med et endepunkt i hver side af snittet. Snitegenskab. For et vilkårligt snit, er den letteste snitkant med i MST. Bevis. Modbevis. Antag den letteste snitkant e for et snit ikke er med i MST. Hvis vi tilføjer e til MST laver vi en kreds. Der er en anden snitkant f i kredsen. Hvis vi fjerner f og tilføjer e har vi et nyt udspændende træ T. Da w(e) < w(f) er w(t) < w(mst). snitkanter e f Kredsegenskab Kredsegenskab. For en vilkårlig kreds, er den tungeste kant i kreds ikke med i MST. Bevis. Modbevis Antag tungeste kant f på en kreds K er indeholdt i MST. Der er lettere kant e i K, der ikke er indeholdt i MST. Hvis vi fjerner f og tilføjer e har vi et nyt udspændende træ T. Da w(f) > w(e) er w(t) < w(mst). Egenskaber for MST Snitegenskab. For et vilkårligt snit, er den letteste snitkant med i MST. Kredsegenskab. For en vilkårlig kreds, er den tungeste kant i kreds ikke med i MST. e f kreds K e e f f
Prims algoritme Mindste udspændende træ Start ved en knude s og opbyg et træ T fra s. I hvert skridt, tilføj letteste kant med netop et endepunkt i T. Stop når T har n- kanter. Introduktion Repræsentation af vægtede grafer Egenskaber for mindste udspændende træer Prims algoritme Kruskals algoritme s Prims algoritme Start ved en knude s og opbyg et træ T fra s. I hvert skridt, tilføj letteste kant med netop et endepunkt i T. Stop når T har n- kanter. Opgave. Håndkør Prims algoritme fra knude på følgende graf. s 9 0 0 9
Prims algoritme Lemma. Prims algoritme beregner MST. Bevis. Kig på snit mellem besøgte og ikke besøgte knuder i et skridt af algoritme. Vi tilføjer letteste snitkant e til T. Snitegenskab kanten e er i MST T er MST efter n- skridt. Prims algoritme Implementation. Hvordan implementerer vi Prims algoritme? Udfordring. Find den letteste kant med netop et endepunkt i T. s s Prims algoritme Implementation. Vedligehold knuder uden for snit i prioritetskø. Nøgle af knude v = letteste kant der forbinder v til træet. I hvert skridt: Find letteste kant = EXTRACT-MIN Opdater vægt af naboer af ny knude med DECREASE-KEY. s 0 0 Prims algoritme PRIM(G, s) for alle knuder v V key[v] = π[v] = null INSERT(P,v) DECREASE-KEY(P,s,0) while (P ) u = EXTRACT-MIN(P) for alle naboer v af u if (v P and w(u,v)<key[v]) DECREASE-KEY(P,v,w(u,v)) π[v] = u Tid. n EXTRACT-MIN n INSERT O(m) DECREASE-KEY Samlet tid med min-hob. O(m log n)
Prims algoritme Theorem. Prims algoritme implementeret med en min-hob beregner en MST i O(m log n) tid. Grådighed. Prims algoritme er eksempel på en grådig algoritme. I hvert skridt, træf det optimale lokale valg. global optimal løsning. Prims algoritme Prioritetskøer og Prim. Kompleksitet af Prims algoritme afhænger af prioritetskø: n INSERT n EXTRACT-MIN m + DECREASE-KEY Prioritetskø INSERT EXTRACT-MIN DECREASE-KEY Total tabel O() O(n) O() O(n binær hob O(log n) O(log n) O(log n) O(m log n) Fibonacci hob O() O(log n) O() O(m + n log n) = amortiseret køretid Kruskals algoritme Mindste udspændende træ Kig på kanter fra letteste til tungeste. I hvert skridt, tilføj kant til T hvis den ikke medfører en kreds i T. Stop når T har n- kanter. Introduktion Repræsentation af vægtede grafer Egenskaber for mindste udspændende træer Prims algoritme Kruskals algoritme 9 9 0
Kruskals algoritme Lemma. Kruskals algoritme beregner MST. Bevis. Algoritme kigger på kanter fra letteste til tungest. To tilfælde for en kant e = (u,v). 0 9 Tilfælde. e danner kreds og bliver ikke tilføjet til T. e er tungeste kant på kreds. Kredsegenskab e er ikke med i MST. Tilfælde. e danner ikke kreds og bliver tilføjet til T. e er letteste kant på snittet givet ved sammenhængskomponenter for u og v. Snitegenskab e er med i MST. T er MST når n- kanter er tilføjet. Kruskals algoritme Implementation. Hvordan implementerer vi Kruskals algoritme? Udfordring. Afgør om en kant danner en kreds. Kruskals algoritme Implementation. Vedligehold kanter i T i datastruktur til dynamiske sammenhængskomponenter. I hvert skridt: Undersøg om kant danner en kreds = CONNECTED. Tilføj ny kant = INSERT. 9 9 9 9 0 0
Kruskals algoritme KRUSKAL(G) Sorter kanter INIT(n) for alle kanter (u,v) i sort. orden if (CONNECTED(u,v)) INSERT(u,v) return indsatte kanter Tid. Sortering af m kanter. INIT m CONNECTED m INSERT Samlet tid med vægtet forening. O(m log m + n + m log n) = O(m log n). Kruskals algoritme Theorem. Kruskals algoritme implementeret med vægtet forening beregner en MST i O(m log n) tid. Grådighed. Kruskals algoritme er også eksempel på en grådig algoritme. Mindste udspændende træ Hvad er det bedste algoritme til MST? Kan man løse problemet i lineær tid? År Tid Opdaget af??? O(n log m) Jarnik, Prim, Dijkstra, Kruskal, Boruvka,? 9 O(m log log n) Yao 9 O(m log* n) Fredman, Tarjan 99 O(m) Karger, Klein, Tarjan 000 O(nɑ(m,n)) Chazelle Mindste udspændende træ Introduktion Repræsentation af vægtede grafer Egenskaber for mindste udspændende træer Prims algoritme Kruskals algoritme 00 optimal Pettie, Ramachandran 0xx O(m)??? = randomiseret køretid
Korteste veje Introduktion Egenskaber for korteste veje Dijkstras algoritme Korteste veje på DAGs Korteste veje Introduktion Egenskaber for korteste veje Dijkstras algoritme Korteste veje på DAGs Philip Bille Introduktion Korteste veje. Givet en orienteret, vægtet graf G og en knude s, find korteste vej fra s til alle knuder i G. Introduktion Korteste veje. Givet en orienteret, vægtet graf G og en knude s, find korteste vej fra s til alle knuder i G. 0 s 9 0 9 s 9 9 0 9
Introduktion Korteste veje. Givet en orienteret, vægtet graf G og en knude s, find korteste vej fra s til alle knuder i G. Korteste veje træ. Repræsentér korteste veje som et træ fra s. Anvendelser Google maps, bilnavigation, rutning i netværk, skedulering, pipelining, 0 s 9 9 0 9 Korteste veje egenskaber Korteste veje Simplificerende antagelse. Alle knuder kan nås fra s. der findes altid (korteste) vej til en knude. Introduktion Egenskaber for korteste veje Dijkstras algoritme Korteste veje på DAGs
Korteste veje egenskaber Lemma. Enhver delvej af en korteste vej er en korteste vej. Bevis. Modbevis. Kig på en korteste vej p fra s til t bestående af p, p og p. p p p s u v t q Antag q er kortere en delvej p. Da er p, q og p en kortere vej fra s til t end p. Korteste veje Introduktion Egenskaber for korteste veje Dijkstras algoritme Korteste veje på DAGs Dijkstras algoritme Mål. Givet en orienteret og vægtet graf G med ikke-negative vægte og en knude s, beregn korteste vej fra s til alle andre knuder. Dijkstras algoritme. Vedligeholder afstandsestimat d[v] for hver knude v = længde af korteste kendte vej til v fra s. Opdaterer afstandsestimater ved at afspænde (relax) kanter. Dijkstras algoritme Sæt d[s] = 0 og d[v] = for alle knuder v V\{s}. Opbyg et træ T fra s. I hvert skridt, tilføj knude v med mindste afstandsestimat til T. Afspænd alle knuder som v peger på. 9 RELAX(u,v) if (d[v] > d[u] + w(u,v)) d[v] = d[u] + w(u,v) s
Dijkstras algoritme Sæt d[s] = 0 og d[v] = for alle knuder v V\{s}. 0 s 9 9 0 0 9 9 Opbyg et træ T fra s. I hvert skridt, tilføj knude v med mindste afstandsestimat til T. Afspænd alle knuder som v peger på. Opgave. Håndkør Dijkstras algoritme fra knude på følgende graf. 9 0 Dijkstras algoritme Notation. δ(s,v) er længden af den korteste vej fra s til v. Lemma. Når afstandsestimater opdateres med afspænding er d[v] δ(s,v) for alle knuder v. Dijkstras algoritme Lemma. Dijkstras algoritme beregner d[v] = δ(s,v) for alle knuder v. Bevis. Modbevis. Lad u være den første knude valgt af algoritmen så d[u] er forkert. Lad P være den korteste vej fra s til u og lad (x,y) være første kant der forlader S. Kig på tidspunkt hvor algoritmen tilføjer u til S: P Vi har: u. d[u] d[y] (alg. valgte u før d[y]). s. d[u] > δ(s,u) (u var forkert). x y Vi har: d[u] > δ(s,u) = w(p) w(p til x) + w(x,y) ( + def.) (P skåret af) = δ(s,x) + w(x,y) (delvej af korteste vej er korteste vej) x S så (x,y) afspændt så: d[y] d[x] + w(x,y) = δ(s,x) + w(x,y) (u er første knude med forkert estimat så d[x] = δ(s,x)) d[u] > δ(s,x) + w(x,y) d[y] i modstrid med.
Dijkstras algoritme Implementation. Hvordan implementerer vi Dijkstras algoritme? Udfordring. Find knude med mindste afstandsestimat. Dijkstras algoritme Implementation. Vedligehold knuder med afstandsestimat i prioritetskø. Nøgle af knude v = d[v]. I hvert skridt: Find knude u med mindste afstandstandestimat = EXTRACT-MIN Afspænd knuder som u peger på med DECREASE-KEY. s s Dijkstras algoritme DIJKSTRA(G, s) for alle knuder v V d[v] = π[v] = null INSERT(P,v) DECREASE-KEY(P,s,0) while (P ) u = EXTRACT-MIN(P) for alle v som u peger på RELAX(u,v) Tid. n EXTRACT-MIN n INSERT O(m) DECREASE-KEY Samlet tid med min-hob. O(m log n) s RELAX(u,v) if (d[v] > d[u] + w(u,v)) d[v] = d[u] + w(u,v) DECREASE-KEY(P,v,d[v]) π[v] = u Dijkstras algoritme Theorem. Dijkstra algoritme implementeret med en min-hob beregner korteste veje i O(m log n) tid. Grådighed. Dijkstras algoritme er eksempel på en grådig algoritme.
Dijkstras algoritme Edsger W. Dijkstra Prioritetskøer og Dijkstra. Kompleksitet af Dijkstras algoritme afhænger af prioritetskø: n INSERT n EXTRACT-MIN m DECREASE-KEY Edsger Wybe Dijkstra (90-00) Prioritetskø INSERT EXTRACT-MIN DECREASE-KEY tabel O() O(n) O() binær hob O(log n) O(log n) O(log n) O(m log n) Fibonacci hob O() O(log n) O() O(m + n log n) = amortiseret køretid Total O(n Dijkstra algoritme. "A note on two problems in connexion with graphs". Numerische Mathematik, 99. Andre bidrag. Grundlæggende resultater i programmering, distribueret beregning, algoritmer, verifikation. Citater. Object-oriented programming is an exceptionally bad idea which could only have originated in California. The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offence. APL is a mistake, carried through to perfection. It is the language of the future for the programming techniques of the past: it creates a new generation of coding bums. Korteste veje på DAGs Udfordring. Er det nemmere at beregne korteste veje på DAGs? Korteste veje DAG korteste veje algoritme. Behandl knuder i topologisk orden. For hver knude v, afspænd alle kanter fra v. Introduktion Virker også for negative kanter. Egenskaber for korteste veje Dijkstras algoritme Korteste veje på DAGs s
Korteste veje på DAGs Lemma. Algoritme beregner d[v] = δ(s,v) for alle knuder v. s Bevis. Induktion over topologisk sortering af knuder v, v,, vn Basis. d[v] = 0 = δ(v,v). Induktionsskridt. vi for i >. d[vi] = min(d[vj] + w(vj, vi)) hvor (vj, vi) er kant i G så j < i. = min(δ(s, vj) + w(vj, vi)) (pga. induktionshypotese) = δ(s, vi) (ingen veje til vi via senere knuder i topologisk orden) Korteste veje på DAGs Implementation. Sorter knuder i topologisk rækkefølge. Afspænd kanter ud af hver knude. Samlet tid. O(m + n). Theorem. Vi kan beregne korteste veje i DAGs i O(m + n) tid. s Korteste veje på DAGs Theorem. Vi kan beregne korteste veje i DAGs i O(m + n) tid. Korteste veje varianter Knuder. Enkelt kilde (single-source): fra s til alle andre knuder. Enkelt kilde, enkelt dræn (single-source single-target): fra s til t. Alle par (all pairs): mellem alle par af knuder. Begrænsninger på kantvægte. Ikke-negative vægte. Vilkårlige vægte. Euklidiske vægte. Kredse. Ingen kredse. Ingen negative kredse.
Korteste veje Introduktion Egenskaber for korteste veje Dijkstras algoritme Korteste veje på DAGs
Hashing Hashing Ordbøger Hægtet hashing Hashfunktioner Lineær probering Ordbøger Hægtet hashing Hashfunktioner Lineær probering Philip Bille Ordbøger Ordbøger. Vedligehold en dynamisk mængde S af elementer. Hvert element har en nøgle key[x] fra et univers af nøgler U og satellitdata data[x]. Ordbogsoperationer. SEARCH(k): afgør om element med nøgle k findes i S, og returner elementet. INSERT(x): tilføj x til S (vi antager x ikke findes i forvejen) DELETE(x): fjern x fra S. Eksempel. U = {0,..,99} key[s] = {,,,,,, 9} U key[s] Ordbøger Anvendelser. Grundlæggende datastruktur til at repræsentere en mængde. Flaskehals i mange algoritmer og datastrukturer.
Hægtet liste Direkte addressering Løsning med hægtet liste. Gem S i hægtet liste. Løsning med direkte addressering (direct addressing). A head 9 SEARCH(k): lineær søgning i listen efter nøgle k. INSERT(x): Indsæt x i start af liste. DELETE(x): fjern x fra liste. Tid. SEARCH i O(n) tid. INSERT og DELETE i O() tid. Plads. O(n). Gem S i tabel A af størrelse U. Gem element x på position A[key[x]] SEARCH(k): returner A[key[x]]. INSERT(x): Sæt A[key[x]] = x. DELETE(x): Sæt A[key[x]] = null. Tid. SEARCH, INSERT og DELETE i O() tid. Plads. O( U ) 0 9 0 9 Ordbøger Datastruktur hægtet liste SEARCH O(n) INSERT O() DELETE O() Plads O(n) direkte addressering O() O() O() O( U ) Udfordring. Kan vi gøre det betydeligt bedre? Hashing Ordbøger Hægtet hashing Hashfunktioner Lineær probering
Hægtet hashing Ide. Find en hashfunktion h : U {0,..., m-}, hvor m = Θ(n). Hashfunktion skal fordele nøglerne fra S nogenlunde jævnt over {0,..., m-}. Hashing = forkludre, sprede, bikse. Hægtet hashing. Gem S i tabel A af størrelse m. Element x gemt i hægtet liste på A[h(key[x])]. Kollision. x og y kolliderer hvis h(key[x]) = h(key[y]). SEARCH(k): lineær søgning i liste A[h(k)] efter nøgle k. INSERT(x): Indsæt x i start af liste A[h(key[x])]. DELETE(x): fjern x fra liste A[h(key[x])]. 0 9 U = {0,..,99} 9 key[s] = {,,,,,, 9} h(k) = k mod 0 Hægtet hashing SEARCH(k): lineær søgning i liste A[h(k)] efter nøgle k. INSERT(x): Indsæt x i start af liste A[h(key[x])]. DELETE(x): fjern x fra liste A[h(key[x])]. Opgave. Indsæt følgende nøglesekvens K =,, 9,, 0,,,, 0 i en hashtabel af størrelse 9 vha. hægtet hashing med hashfunktionen h(k) = k mod 9. Hægtet hashing Uniform hashing SEARCH(k): lineær søgning i liste A[h(k)] efter nøgle k. INSERT(x): Indsæt x i start af liste A[h(key[x])]. DELETE(x): fjern x fra liste A[h(key[x])]. Tid. SEARCH i O(længde af liste) tid. INSERT og DELETE i O() tid. Længde af lister er afhængig af hashfunktion. Plads. O(m + n) = O(n). 0 9 Def. Belastningsfaktor α = n/m = gennemsnitlig længde af lister. m = Θ(n) α = O(). Simpel uniform hashing. Antag at hvert element afbildes uniformt tilfældigt i A. Forventet længde af liste = α. forventet tid for SEARCH er O() Tid. SEARCH i O() forventet tid. INSERT og DELETE i O() tid. 0 9 9 9 U = {0,..,99} key[s] = {,,,,,, 9} h(k) = k mod 0 U = {0,..,99} key[s] = {,,,,,, 9} h(k) = k mod 0
Ordbøger hægtet liste O(n) O() O() O(n) direkte addressering O() O() O() O( U ) Datastruktur SEARCH INSERT DELETE Plads hægtet hashing O() O() O() O(n) = forventet køretid med antagelse om simpel uniform hashing Udfordring. Hvad kan vi gøre uden at antage simpel uniform hashing? Findes der hashfunktioner der fordeler en mængde nøgler nogenlunde jævnt? Hashing Ordbøger Hægtet hashing Hashfunktioner Lineær probering Hashfunktioner Divisionsmetoden. h(k) = k mod m, hvor m er et primtal. Primtal m fordi fælles divisorer af nøgler og m kan reducere udnyttelse af tabel. h(k) = ak mod m er lidt bedre. Multiplikationsmetoden. h(k) = m(kz - kz ), hvor Z er en konstant 0 < Z <. Hashfunktioner Hashfunktioner for andet end heltal. Alt er gemt som bits og kan derfor hashes. Flydende tal. Konverter til bitrepræsentation. Strenge. Bogstaver er heltal og så streng kan konverteres til sekvens af cifre. F. eks. "CLRS": forskellige ASCII-koder for bogstaver. C =, L =, R = og S =. "CLRS" = + + + 0 = 90 Andre objekter. Definer hashfunktion baseret på datafelter.
Universel hashing Kan vi konstruere hashfunktioner med beviselige garantier uden antagelse om uniform hashing? Ide. Vælg en tilfældig hashfunktion h uniformt tilfældigt fra en mængde H af funktioner der kan beskrives kompakt og beregnes hurtigt. For alle k k i U skal Pr[h(k) = h(k)] /m. Eksempel. ha,b(k) = (ak + b mod p) mod m for primtal p H = {ha,b(k) a {,.., p-}, b {0,..., p-}} Universel hashfunktion Kædet hashing i O() forventet tid uden antagelse om uniform hashing. Kun afhængig af tilfældigt valg fra H. Hashing Anvendelser. Kodning, kryptografi, similaritet, geometri,... Lineær probering Hashing Ordbøger Hægtet hashing Hashfunktioner Lineær probering Lineær probering (linear probing). Gem S i tabel A af størrelse m. Element x gemt i A[h(key[x])] eller i klynge (cluster) til højre for A[h(key[x])]. Klynge = fortløbende (cyklisk) sekvens af fyldte indgange. 9 0 9 h(k) = k mod 0 SEARCH(k): lineær søgning fra A[h(key[x])] i klynge til højre for A[h(key[x])] INSERT(x): indsæt x på A[h(key[x])]. Hvis optaget, indsæt på næste tomme indgang til højre for x. DELETE(x): fjern x fra A[h(key[x])]. Genindsæt alle elementer til højre for i klyngen.
Lineær probering Caching. Linæer probering er meget cache-effektivt. Klumpning (clustering). Nøgler har en tendens at "klumpe" sammen. 9 0 9 h(k) = k mod 0 Theorem. Med antagelse om simpel uniform hashing er det forventede antal proberinger i A /( - α), hvor α = n/m er belastningsfaktoren (load factor). Lineær probering Lineær probering vs. hægtet hashing. http://en.wikipedia.org/wiki/hash_table Åben addressering Åben addressering (open addressing). Linæer probering. Kvadraktisk probering. Dobbelt hashing. Hashing Ordbøger Hægtet hashing Hashfunktioner Lineær probering
Binære søgetræer Binære søgetræer Nærmeste naboer Binære søgetræer Indsættelse Predecessor og successor Sletning Trægennemløb Nærmeste naboer Binære søgetræer Indsættelse Predecessor og successor Sletning Trægennemløb Philip Bille Nærmeste naboer Nærmeste naboer. Vedligehold en dynamisk mængde S af elementer. Hvert element har en nøgle key[x] og satellitdata data[x]. Nærmeste naboer operationer. PREDECESSOR(k): returner element x med største nøgle k. SUCCESSOR(k): returner element x med mindste nøgle k. INSERT(x): tilføj x til S (vi antager x ikke findes i forvejen) DELETE(x): fjern x fra S. Nærmeste nabo Anvendelser. Søgning efter relateret data (typisk mange dimensioner). Rutning på internettet. 0 0 PREDECESSOR() k = SUCCESSOR()
Hægtet liste Løsning med hægtet liste. Gem S i en dobbelt-hægtet liste. head 9 PREDECESSOR(k): lineær søgning i listen efter element med største nøgle k. SUCCESSOR(k): lineær søgning i listen efter element med mindste nøgle k. INSERT(x): indsæt x i starten af liste. DELETE(x): fjern x fra liste. Tid. PREDECESSOR og SUCCESSOR i O(n) tid. INSERT og DELETE i O() tid. Plads. O(n). Binær søgning Løsning med sorteret tabel. Gem S i tabel sorteret efter nøgle. 9 PREDECESSOR(k): binær søgning i listen efter element med største nøgle k. SUCCESSOR(k): binær søgning i listen efter element med mindste nøgle k. INSERT(x): lav ny tabel af størrelse + med x tilføjet. DELETE(x): lav ny tabel af størrelse - med x fjernet. Tid. PREDECESSOR og SUCCESSOR i O(log n) tid. INSERT og DELETE i O(n) tid. Plads. O(n). Nærmeste nabo Datastruktur PREDECESSOR SUCCESSOR INSERT DELETE Plads hægtet liste O(n) O(n) O() O() O(n) binær søgning O(log n) O(log n) O(n) O(n) O(n) Binære søgetræer Nærmeste naboer Binære søgetræer Indsættelse Predecessor og successor Sletning Trægennemløb
Binære søgetræer Binære søgetræer Binært træ. Et binært træ er enten Tomt. En knude med to binære træer som børn. Binært søgetræ. Binært træ der overholder søgetræsinvarianten. Søgetræsinvariant (binary-search-tree property). Alle knuder indeholder et element. For alle knuder v: alle nøgler i venstre deltræ er key[v]. alle nøgler i højre deltræ er key[v]. v 0 Repræsentation. Hver knude x består af root key[x] left[x] null right[x] parent[x] (data[x]) Plads. O(n) 0 null null null null null 0 null null key[v] key[v] null null Indsættelse INSERT(x): start i rod. Ved knude v: Binære søgetræer hvis key[x] key[v] gå til venstre. hvis key[x] > key[v] gå til højre. hvis null, indsæt x Nærmeste naboer Binære søgetræer Indsættelse Predecessor og successor Sletning Trægennemløb 0 INSERT(9) 9 0
Indsættelse Indsættelse INSERT(x): start i rod. Ved knude v: hvis key[x] key[v] gå til venstre. hvis key[x] > key[v] gå til højre. hvis null, indsæt x Opgave. Indsæt følgende nøglesekvens i binært søgetræ:,,,,, 9,,, INSERT(x,v) if (v == null) return x if (key[x] < key[v]) left[v] = INSERT(x, left[v]) if (key[x] > key[v]) right[v] = INSERT(x, right[v]) Tid. O(h) 9 0 Predecessor Binære søgetræer Nærmeste naboer Binære søgetræer Indsættelse Predecessor og successor Sletning Trægennemløb PREDECESSOR(k): start i rod. Ved knude v: k == key[v]: returner v. k < key[v]: fortsæt søgning i venstre deltræ. k > key[v]: fortsæt søgning i højre deltræ. Hvis der ikke findes knude i højre deltræ med nøgle k, returner v. key[v] v key[v]
Predecessor PREDECESSOR(v, k) if (v == null) return null if (key[v] == k) return v if (key[v] < k) return PREDECESSOR(left[v], k) t = PREDECESSOR(right[v], k) if (t null) return t else return v Tid. O(h) SUCCESSOR med tilsvarende algoritme i O(h) tid. key[v] v key[v] Binære søgetræer Nærmeste naboer Binære søgetræer Indsættelse Predecessor og successor Sletning Trægennemløb Sletning Sletning DELETE(x): x har 0 børn: slet x. DELETE(x): x har 0 børn: slet x. x har barn: split x ud. 0 børn barn x x
Sletning DELETE(x): x har 0 børn: slet x. x har barn: split x ud. x har børn: find y = SUCCCESSOR(key[x]). Split y ud og udskift y med x x børn x y Sletning DELETE(x): x har 0 børn: slet x. x har barn: split x ud. x har børn: find y = SUCCCESSOR(key[x]). Split y ud og udskift y med x. Tid. O(h) y y Binære søgetræer Tid. PREDECESSOR, SUCCESSOR, INSERT og DELETE i O(h) tid. Højden h er afhængig sekvens af operationer. I værstefald er h = Ω(n). I gennemsnit er h = Θ(log n). Med balancerede søgetræer (- træer, AVL-træer, rød-sorte træer,..) tager alle operationer O(log n) tid i værstefald. Plads. O(n). Nærmeste nabo Datastruktur PREDECESSOR SUCCESSOR INSERT DELETE Plads hægtet liste O(n) O(n) O() O() O(n) binær søgning O(log n) O(log n) O(n) O(n) O(n) binært søgetræ O(h) O(h) O(h) O(h) O(n) balanceret søgetræ O(log n) O(log n) O(log n) O(log n) O(n)
Trægennemløb Binære søgetræer Nærmeste naboer Binære søgetræer Indsættelse Predecessor og successor Sletning Trægennemløb Inorder gennemløb (inorder traversal). Besøg venstre deltræ rekursivt. Besøg knude. Besøg højre deltræ rekursivt. 0 Inorder:,,,,,,, 0 Udskriver knuderne i et binært søgetræ i sorteret rækkefølge. Tid. O(n) Trægennemløb Preorder gennemløb (preorder traversal). Besøg knude. Besøg venstre deltræ rekursivt. Besøg højre deltræ rekursivt. Tid. O(n) 0 Preorder:,,,,,,, 0 Trægennemløb Postorder gennemløb (postorder traversal). Besøg venstre deltræ rekursivt. Besøg højre deltræ rekursivt. Besøg knude. 0 Postorder:,,,,,, 0, Tid. O(n)