Masterteoremet 1
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! 2
Tilfelle 1: Løvnodene dominerer Da blir kostnaden (n log b a ) Det skjer når f(n) = O(n log b a ) 3
Tilfelle 2: «Dødt løp» Da blir kostnaden Det skjer når (n log b a lg n) Samme kostnad i hvert nivå (dvs. det samme som løvnodene); vi ganger med høyden. f(n) = (n log b a ) 4
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. 5 f(n) er da regulær
Tilfelle 3: Rota dominerer Da blir kostnaden Det skjer når (f(n)) 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) = (n log b a+ ) 6 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) 7
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) 8
Variabelskifte 9
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 ) 10
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) 11
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. 12
deeegimnoorrrsstt Sjette forelesning 13
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? 14
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. 15
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!16
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. 17 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!) :)
Men hvor effektivt kan det bli? Ω(n lg n) 18
Se kap. 8 Hver sammenligning halverer antall muligheter. Vi starter med n! mulige rekkefølger. Beste «worst-case» blir lg(n!) Nyttig: Stirlings approksimasjon: 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) 19
Med andre ord lg n! = Ω(n lg n) 20
Heapsort 21
22
p(i) = i/2 l(i) = 2i r(i) = 2i + 1 23
Heapify 24
16 4 10 14 7 9 3 2 8 1 25
16 14 10 4 7 9 3 2 8 1 26
16 14 10 8 7 9 3 2 4 1 27
På tavla: Kjøretid Korrekthet (invariant) Build-Heap(A, n): for i floor(n/2) downto 1 Heapify(A, i, n) 28
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) 29
Insert(S, x) Maximum(S) Extract-Max(S) Increase-Key(S, x, k) 30
Sortering «Selection sort» med en heap In-place, enkel O(n lg n) Heapsort 31
M g O g r e 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 32
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) Te gning/forklar ing på tavla. 33
Invariant: 34
Invariant: 35
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 36
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 37
Average-case Intuisjon: Selv om annenhvert nivå er helt skjevt vil det bare øke kjøretiden med en konstant. 38
Sortering Store/små for seg Rekursivt Kjapp O(n 2 ) WC O(n lg n) Avg. Quicksort 39
Sortering Splitt og hersk og flett Stabil Ikke in-place O(n lg n) Mergesort 40
Vi slår den nedre grensen ved å «spille et annet spill» Lineær sortering 41
Lineær sortering Counting sort 42
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 43
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) 44
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? 45
Sorter heltall Eller lignende Verdier O(n) Tell forekomster Regn ut indeks Lineær Strenge krav O(n) Tellesortering 46
Lineær sortering Radix sort 47
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 48
49
50
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! 51 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 52 Evt. gruntallssortering :-)
Lineær sortering Bucket sort 53
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 54
Bøttene sorteres (med en enkel algoritme) Hver bøtte har O(1) forventet størrelse Totalt O(n) kjøretid 55
Sortering Uniformt [0,1) Ordnet hashing Lineær Krav O(n) Bøttesortering 56
Select 57
Seleksjon: Finn i-ende ordens statistic Eksempler: minimum, maksimum, median min/maks: enkle spesialtilfeller Vi ønsker ikke å sortere 58
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 59 Regnes på tavla.
Select Hårete og søt 60
Denne algoritmen er fra 1973. Høsten 2014 viste Chen og Dumitrescu at den også fungerer om man deler i grupper på 3 eller 4. http://arxiv.org/abs/1409.3600 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. 61 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 62
Finn median Og lignende Pivot = m. av m. finnes rekursivt Kjapp O(n) Select 63