deeegimnoorrrsstt Sjette forelesning 1
2
Bellman-Ford BFS/DFS Binære søketrær Binærsøk Bubblesort Bucket sort Counting sort Dijkstra DAGshortest-path Edmonds- Karp Floyd- Warshall Hashing Heapsort Huffmankoding Insertion sort Kruskal Merge sort Prim Quicksort Radix sort Randomized Select Select Selection sort Sterke komponenter Topologisk sortering 3
Bellman-Ford BFS/DFS Binære søketrær Binærsøk De gjenværende algoritmene er litt mer omfattende. (Mange av sorteringsalgoritmene Bubblesorther er ganske enkle, f.eks.) Bucket sort Counting sort Dijkstra DAGshortest-path Edmonds- Karp Floyd- Warshall Hashing Heapsort Huffmankoding Insertion sort Kruskal Merge sort Prim Quicksort Radix sort Randomized Select Select Selection sort 4 Sterke komponenter I tillegg: Eksempler (DP, LP) NPC-problemer Topologisk sortering
Gjensyn med masterteoremet 5
Masterteoremet 6
T (n) = at (n/b) + f(n) Antall «barn»: Størrelse per «barn»: «Høyde»: a n/b log b n = Θ(lg n) Rota har f(n) arbeid; hver løvnode har en konstant mengde arbeid. Hva vil dominere totalen? Det kommer an på forholdet mellom f(n) og antallet løvnoder. Antall «løvnoder»: a log b n = n log b a Husk uttrykket for antall løvnoder! 7
Tilfelle 1: Løvnodene dominerer Da blir kostnaden Θ(n log b a ) Det skjer når f(n) = O(n log b a ɛ ) 8
Tilfelle 2: «Dødt løp» Da blir kostnaden Det skjer når Θ(n log b a lg n) f(n) = Θ(n log b a ) Samme kostnad i hvert nivå (dvs. det samme som løvnodene); vi ganger med høyden. 9
Det finnes en c < 1 s.a. af(n/b) cf(n), for store nok verdier n Det vil intuitivt si at f-en krymper nedover i treet. 10 f(n) er da regulær
Tilfelle 3: Rota dominerer Da blir kostnaden Det skjer når Θ(f(n)) f(n) = Ω(n log b a+ɛ ) 11 Regulariteten innebærer, for en c < 1 og store n: a*f(n/b) c*f(n). Trenger ikke sjekkes hvis f(n) er polynomisk (dvs. n^k). f(n) må være regulær!
T (n) = { 1 if n = 1 2T (n/2) + n if n > 1 a = 2 b = 2 log b a = 1 n log b a = n f(n) = n = Θ(n log b a ) Her er det dødt løp, så vi får høyde * antall løvnoder = høyde * radsummen, som vi jo kjenner så godt fra treet vårt T (n) = Θ(n log b a lg n) = Θ(n lg n) 12
T (n) = { 1 if n = 1 2T (n/2) + n if n > 1 a = 2 b = 2 log b a = 1 n log b a = n f(n) = n = Θ(n log b a ) Her er det dødt løp, så vi får høyde * antall løvnoder = høyde * radsummen, som vi jo kjenner så godt fra treet vårt T (n) = Θ(n log b a lg n) = Θ(n lg n) 13
Variabelskifte 14
Flytter oss til «en enklere verden» Skift funksjon og variabel; går «opp i opp» T(n) = S(m) F.eks. m = lg n, S(m) = T(2m ) 15
T (n) = 2T ( n) + lg n [m = lg n] T (2 m ) = 2T (2 m/2 ) + m [S(m) = T (2 m )] S(m) = 2S(m/2) + m = O(m lg m) T (n) = O(lg n lg lg n) 16
T (n) = 2T ( n) + lg n [m = lg n] T (2 m ) = 2T (2 m/2 ) + m [S(m) = T (2 m )] S(m) = 2S(m/2) + m = O(m lg m) T (n) = O(lg n lg lg n) Legg merke til at alle venstresidene (og høyresidene, for den saks skyld) er like. 17
Rebus. Hva er dette? Svar: Kvadratiske sorteringsalgoritmer :-> Som vanlig relativt abstrakte beskrivelser her. Ta en titt på pseudokode i boka for mer detaljert arrayelement-skyfling. sorteri ngsalgo ritmer. Nært Brute Force, men ikke helt. Hva vil brute force (type prøv alle muligheter e.l.) være for sortering? 18
Merk: Samme mønster som Bellman-Ford, på sett og vis. Tilsynelatende bare overfladisk, men egentlig et generelt mønster. Bubble Sort Normalt: Sammenlign alle par i rekkefølge fra venstre til høyre. Tenk etter: Vil det fungere om du i hver iterasjon fikser parene i tilfeldig rekkefølge? Beviset blir helt klart ikke det samme, men blir det korrekt likevel? Gjenta n ganger: Sammenlign og evt. fiks alle n 1 par Utfør fra venstre til høyre i hver iterasjon. I hver iterasjon vil da det største usorterte elementet ha falt på plass. n iterasjoner gir da fullstendig sortering. 19
Selection Sort Gjenta n ganger: Finn det største usorterte elementet Bytt plass med det siste usorterte Nærmest en direkte implementasjon av korrekthetsbeviset til Bubble Sort!20
Insertion Sort Gjenta n ganger Sett inn første usorterte blant sorterte De sorterte havner i starten. Man leter etter riktig plass. Merk at man ofte lar elementet synke ned til riktig plass, så man setter det inn mens man leter. Det kan evt. gjøres ved å bare duplisere neste element hele veien, og så sette inn elementet direkte når man har funnet rett plass. 21 Oppgave : Tenk ut din egen sorteringsalgoritme med kvadratisk kjøretid. Om du ikke klarer det, prøv en med kjøretid på O(2^n) eller O(n!) :)
Stå på eksamen uten å lese! 22
23
And I was really impressed with how they managed to shock the Goatse guy. 24 http://xkcd.com/351/
Men hvor effektivt kan det bli? Ω(n lg n) 25
Se kap. 8 Hver sammenligning halverer antall muligheter. Vi starter med n! mulige rekkefølger. Beste «worst-case» blir lg(n!) :"+76#'391.23("391/2.,/ 91.23!391/2! - 91.23-391/234&5673$%36##689 /,) 91.23!391/2.,)! - 91/23-391)2! - ".0/0)#.,) "/0.0)# /,)! - Nyttig: 91.23!391/23!391)2! Stirlings - approksimasjon: 91.23-391/2 91.23-391)2 ".0)0/# ")0.0/# "/0)0.# ")0/0.# n! > (n/e)^n Dermed: h lg(n!) lg(n/e)^n = n lg(n/e) = n lg n - n lg e = Omega(n lg n) 26
Med andre ord lg n! = Ω(n lg n) 27
Heapsort 28
< D C > E = A @ B <? <= <> <? @ A B C D > < 29
< D C > E = A @ B <? <= <> <? @ A B C D > < p(i) = i/2 l(i) = 2i r(i) = 2i + 1 < D C > E = A @ B <? <= <> <? @ A B C D > < 30
Heapify 31
16 4 10 14 7 9 3 2 8 1 32
16 14 10 4 7 9 3 2 8 1 33
16 14 10 8 7 9 3 2 4 1 34
På tavla: Kjøretid Korrekthet (invariant) Build-Heap(A, n): for i floor(n/2) downto 1 Heapify(A, i, n) 35
Korrekthet vises enkelt induktivt. Eksempel på tavla. Heapsort(A, n): Build-Max-Heap(A, n) for i n downto 2 exchange A[1] and A[i] Max-Heapify(A, 1, i 1) 36
Operasjonene forklart på tavla. Viktig: Hvordan elementer kan «flyte» oppover eller «synke» nedover til riktig plass. Insert(S, x) Maximum(S) Extract-Max(S) Increase-Key(S, x, k) 37
Sortering «Selection sort» med en heap In-place, enkel O(n lg n) Heapsort 38
M g O e rg t r o es Dårlig worst-case, men bra average-case. Lave konstantledd. Mergesort virker på en måte «omvendt». QS er in-place; MS er det ikke. MS har bedre worst-case. Quicksort 39
Grunn-idé Korrekthet vises induktivt. Kjøretiden gis av vårt velkjente binærtre. Del sekvensen i to Sorter hver halvdel rekursivt Kombinér etterpå (Mergesort) eller rydd litt først (Quicksort) Tegning/forklaring på tavla. 40
2 2.67 &! " # $ % & ' (. 7 &! " # $ % & ' (.62 7 & "! # $ % & ' (.62 7 & "! # $ % & ' (. 2 7 & " $ #! % & ' (. 2 7 & " $ %! # & ' (. 2 7 & " $ % & #! ' (. 2 & " $ % & #! ' (. 2 & " $ % & (! ' # Invariant: 41 8)&*+, -./01 8)7,22,&3"*+, 401,561,6789.46: 8)2;",22,73"*+, <40=4,10,>6,?,-./01 8).,22,2*+, <40=4,10,>6,!,-./01
2 2.67 &! " # $ % & ' (. 7 &! " # $ % & ' (.62 7 & "! # $ % & ' (.62 7 & "! # $ % & ' (. 2 7 & " $ #! % & ' (. 2 7 & " $ %! # & ' (. 2 7 & " $ % & #! ' (. 2 & " $ % & #! ' (. 2 & " $ % & (! ' # Invariant: 42 8)&*+, -./01 8)7,22,&3"*+, 401,561,6789.46: 8)2;",22,73"*+, <40=4,10,>6,?,-./01 8).,22,2*+, <40=4,10,>6,!,-./01
Merge Enkelt eksempel på tavla. Du har to sorterte (del-)sekvenser Plukk ett av sekvens-«hodene» Velg hele tiden det minste Legg det inn på neste ledige plass i resultatet 43
Kjøretid Worst-case for MS og Best-case for QS T(n) = 2T(n/2) + n Selv 9-til-1-split gir Θ(n log n) for QS Average-case blir også Θ(n log n) Skjev split for QS gir kvadratisk WC Randomisering: Unngår data-avhengig WC 44
Average-case Intuisjon: Selv om annenhvert nivå er helt skjevt vil det bare øke kjøretiden med en konstant. 6!B6C 6!B6C? 6@A B6@ACDEF@FA B6@ACDE B6@ACDE B6@ACDE 45
Sortering Store/små for seg Rekursivt Kjapp O(n 2 ) WC O(n lg n) Avg. Quicksort 46
Sortering Splitt og hersk og flett Stabil Ikke in-place O(n lg n) Mergesort 47
http://www.smbc-comics.com/index.php?db=comics&id=1989 48
49
50
51
52
53
54
Vi slår den nedre grensen ved å «spille et annet spill» Lineær sortering 55
Lineær sortering Counting sort 56
Inn: A[1 n], der A[i] {0, 1,, k} Ut: B[1 n], sortert Ekstralager: C[0 k] Vi bruker C til å telle forekomster 57
Tell hvor mange vi har av hver Gjør telle-tabellen (C) kumulativ Tallet angir nå posisjonen til den siste forekomsten Gå igjennom A (baklengs) og bruk C til å finne posisjon Oppdater C etter hvert (dekrementer posisjonen) 58
for i = 0 to k C[i] = 0 for j = 1 to n C[A[j]] = C[A[j]] + 1 for i = 1 to k C[i] = C[i] + C[i 1] for j = n downto 1 B[C[A[j]]] = A[j] C[A[j]] = C[A[j]] 1 Her gjelder det å gå systematisk til verks Her har vi «downto» for å holde sorteringen stabil. Ser du hvorfor det må være sånn? Bonusspørsmål: Klarer du å lage en versjon som *ikke* bruker downto, men som er stabil likevel? 59
Kø-sortering En måte å se «koblingen» på er at vi i tellesortering først holder rede på hvor lange køene er, og deretter på En lignende sak hvor køene slutter. En forskjell er at vi henter verdier fra hver kø i tilfeldig rekkefølge. Opprett en FIFO-kø for hver mulig verdi For hvert input-element: Legg bakerst i riktig kø Slå sammen køer Fyll output med verdier fra køen Denne algoritmen er også en svært nær slektning (en slags heltallsvariant) av bøttesortering (forklares litt senere). 60 Dette kan enten ses som en konseptuell forklaring av (nesten) hva som skjer i tellesortering (det kan kreve litt tenking å se «ekvivalensen») eller som en egen, enkel, lineær-tids sorteringsalgoritme.
Sorter heltall Eller lignende Verdier O(n) Tell forekomster Regn ut indeks Lineær Strenge krav O(n) Tellesortering 61
Lineær sortering Radix sort 62
Sorter hvert siffer for seg Bruk en stabil sortering (f.eks. CS) for å bevare arbeidet så langt Vi må begynne med minst signifikante siffer Konstant antall siffer: Lineær kjøretid 63
A09>3H <:P T;< P+R R<; ];. T<; ]+T PV+ PV+ ];. T;< ]+T R<; T<; <:P P+R ]+T P+R <:P R<; T<; ];. T;< PV+ <:P T<; T;< P+R PV+ ]+T ];. R<; 64
A09>3H <:P T;< P+R R<; ];. T<; ]+T PV+ PV+ ];. T;< ]+T R<; T<; <:P P+R ]+T P+R <:P R<; T<; ];. T;< PV+ <:P T<; T;< P+R PV+ ]+T ];. R<; 65
Hva om tallene har ulikt antall siffer? Hva om det er veldig stor forskjell? Kan vi få til O(m), der m er det totale antall siffer brukt? (Det ville kunne brukes på vilkårlige strenger også.) Bryter vi i så fall den nedre grensen vår? Korrekthet kan vises ved induksjon på antall pass Kjøretid Θ(n + k) (evt. Θ((n + k)d) Hvordan bryter radix sort reglene for sammenligningssortering? Vi kan få informasjon ut over bare å sammenligne to nøkler. Vi bruker nøkler som tabellindekser! 66 Det kan vi gjøre fordi vi kjenner verdiområdet.
Sorter heltall Eller lignende Verdier O(n k ) Sorter siffer Stabilt Lineær Ganske strenge krav O(kn) Radikssortering 67 Evt. gruntallssortering :-)
Lineær sortering Bucket sort 68
Anta uniformt fordelte verdier i [0,1) Del [0,1) i n like store bøtter Fordél verdiene i bøttene Gå igjennom bøttene i rekkefølge Skriv ut verdiene sortert 69
Bøttene sorteres (med en enkel algoritme) Hver bøtte har O(1) forventet størrelse Totalt O(n) kjøretid 70
Sortering Uniformt [0,1) Ordnet hashing Lineær Krav O(n) Bøttesortering 71
Select 72
Seleksjon: Finn i-ende ordens statistic Eksempler: minimum, maksimum, median min/maks: enkle spesialtilfeller Vi ønsker ikke å sortere 73
I stedet for å sortere begge halvdeler fortsetter vi bare i den som inneholder posisjon i, som er den vi leter etter. Randomized-Select Eksempel på tavla..5 Quicksort Verste tilfelle blir som for Quicksort. Beste tilfelle blir Theta(n). Forventet kjøretid, forenklet: T(n) = T(n/2) + n 74 Regnes på tavla.
Select Hårete og søt 75
Del i grupper på 5, og finn medianen i hver Finn «medianen til medianene», rekursivt Bruk denne som pivot i Partition Select rekursivt på «halvparten» Median-av-5: Konstant tid (insertion sort, f.eks.) for hver; O(n) totalt. Median-av-medianer: T(n/5). Merk: Etter utført algoritme vil dataene allerede være partisjonerte rundt elementet vi leter etter. Så ved å kjøre select etter element k så finner vi automatisk de k minste elementene i tabellen. 76 Partition: O(n). Rekursivt kall T(7n/10 + 6), hvis T(n) er monotont stigende. Mao: Vi får en «prosent-deling» i rekursjonen.
Finn median Og lignende Halv Quicksort Kjapp O(n 2 ) WC O(n) Avg. Randomized Select 77
Finn median Og lignende Pivot = m. av m. finnes rekursivt Kjapp O(n) Select 78
Bellman-Ford BFS/DFS Binære søketrær Binærsøk Bubblesort Bucket sort Counting sort Dijkstra DAGshortest-path Edmonds- Karp Floyd- Warshall Hashing Heapsort Huffmankoding Insertion sort Kruskal Merge sort Prim Quicksort Radix sort Randomized Select Select Selection sort Sterke komponenter Topologisk sortering 79
Bellman-Ford BFS/DFS Binære søketrær Binærsøk Bubblesort Bucket sort Counting sort Dijkstra DAGshortest-path Edmonds- Karp Floyd- Warshall Hashing Heapsort Huffmankoding Insertion sort Kruskal Merge sort Prim Quicksort Radix sort Randomized Select Select Selection sort Sterke komponenter Topologisk sortering 80