Algorithms and Architectures I Rasmus Løvenstein Olsen (RLO), Jimmy Jessen Nielsen (JJE) Mm6: More sorting algorithms: Heap sort and quick sort - October 9, 008
Algorithms and Architectures II. Introduction to analysis and design of algorithms(rlo). Recursive algorithms and recurrences (RLO). More about recurrences (RLO) 4. Greedy algorithms, backtracking and more recurrences(rlo) 5. Counting, probabilities and randomized algorithms (RLO) 6. More sorting algorithms: Heap sort and quick sort (RLO) 7. A little bit more about sorting - and more times for exercises (RLO) 8. Hash tables, Hashing and binary search trees (RLO) 9. Binary search trees, red-black trees (JJE) 0. Red-black trees continued + string matching (JJE)
Dagsorden Heap sort Hvad er en heap? Basale heap operationer Vedligeholdelse af heap egenskabet under sortering Gennemgang af heap sort via eksempel Anvendelse af heap sort: Prioritetskøer Quick sort Virkemåde Partitionering af array Ydelse af quick sort Effektivisering vha. randomiseret input Opsummering og konklusion Opgaver
Sortering af data Sortering af data sker mange steder Data baser Regneark Videnskabelig analyse af måle data Flere eksempler på sorteringsalgoritmer Heap sort Organisering af data i såkaldte heaps Quick sort Re-arrangering af data efter valgt pivot punkt Counting sort Baserer sig på antal af specifikke elementer og udnytter specifik viden om data Bucket sort Re-organisering af data i buckets 4
Hvad er en heap? En (binær) heap er en data struktur der kan karakteriseres som et array med et næsten komplet binært træ A Et array A der representerer sådan en struktur indeholder Længde : length[a] Heap størrelse : heap-size[a] heap-size[a] length[a] Grafisk representation D B E C A B C D E 5
Heap specifikke operationer Parent(i) Return(i/) Left(i) Return i Right(i) Return i+ 4 5 8 9 0 6
Max-heap og min-heap Max-heap egenskab A[parent(i)] A[i] Det største element er root elementet, og alle under elementer har værdier mindre end elemente selv Min-heap egenskab A[parent(i)] A[i] Det mindste element er root elementet, og alle under elementer har værdier større end elementet selv Egenskaberne bliver udnyttet i forskellige sammenhæng, f.eks. Prioritetskøer og sorteringsalgoritmer Vi ser på heapsort der udnytter disse egenskaber og kigger på flg. Procedurer Max-heapify: Sikrer vores heap egenskaber bibeholdes, T(n) = O(log(n)) Build-max-heapify: Producerer en max-heap fra et usorteret input, T(n) = O(n) Heapsort algoritme: Sorterer arrayet, T(n) = O(nLog(n)) 7
Vedligeholdelse af heap egenskab MAX-HEAPIFY Input til algoritme: et array A og et indeks i til arrayet MAX-HEAPIFY (A, i) L = Left(i) 6 If R heap-size[a] and A[r]>A[largest] R = Right(i) 7 then largest = R If L heap-size(a) and A[L] > A[i] 8 If largest i 4 then largets = L 9 then exchange A[i] with A[largest] 5 else largest = i 0 MAX-HEAPIFY(A, largest) Vi antager de binære træer, med rod i Left[i] og Right[i] er maxheaps A[i] er derimod muligvis mindre end dens undergrene 8
Eksempel med Max-heapify Heap-size[A] = 0 Initial værdi af A A[] = 4 bryder max-heap egenskabet idet den ikke er større end dens to undergrene Vi skal have flyttet den således vi genskaber/ opnår max-heap egenskab 6 4 0 4 5 4 7 9 8 9 0 8 9
Eksempel med Max-heapify # Ved udskiftning med A[4] opnår vi: Genoprettelse/opnåelse af maxheap egenskab for node Vi har nu A[4] = 4 > A[9] Ødelæggelse af max-heap egenskab for node 4 Vi skal have flyttet mere rundt på tingene 6 4 0 4 5 4 7 9 8 9 0 8 0
Eksempel med Max-heapify # Ved rekursivt kald til max-heapify opnår vi: A[9] = 4, A[4] = 8 Dermed har vi opnået et max-heap egenskab for det binære træ 6 4 0 4 5 8 7 9 8 9 0 4
Max-heapify algoritme kompleksitet Eksekveringstiden for max-heapify algoritmen er flg. Θ() for at genoprette forholdet mellem A[i], A[Left(i)] og A[Right(i)] plus tiden for at udføre max-heapify på en af de underliggende knudepunkter De enkelte undergrene har hver maksimalt n/ elementer værste tilfælde når den sidste række er fyldt helt op (hvorfor det er n/ er en af dagens opgaver ) Dermed er rekursiviteten givet ved T ( n) T (n / ) + Θ() Den har vi set før... Og giver T(n) = O(log (n))
Konstruering af en heap Vi kan nu benytte os af Max-Heapify til at konvetere et array A[..n] til en max-heap Build-Max-Heap (A) Heap-size[A] = length[a] For i = length[a]/ downto do Max-Heapify (A,i)
Hvordan Build-Max-heap virker - grafisk 4 4 6 9 0 4 8 7 4 5 6 9 0 8 9 0 4 8 7 4 4 5 6 9 0 8 9 0 4 8 7 4
Hvordan Build-Max-heap virker grafisk # 4 4 5 4 6 9 0 8 9 0 8 7 4 0 4 5 4 6 9 8 9 0 8 7 5
Hvordan Build-Max-heap virker grafisk # 4 6 0 4 5 4 7 9 8 9 0 8 6 4 0 4 5 8 7 9 8 9 0 4 6
Bevis for korrekthed af Build-Max-Heap Loop invariant defineres som Ved begyndelsen af hver iteration af For loopet i linie -, er knudepunkterne i+, i+,... N roden af en max-heap Initialisering af algoritmen: Pga. konstruktionen af en heap bliver elementerne n/ +, n/ +,..., n automatisk klassificeret som endepunkter i træet. Det er det samme som de er rod for et -element stort max-heap. Derfor holder loop invarianten under initialisering af algoritmen. 4 5 8 9 0 4 5 8 9 0 7
Bevis for korrekthed af Build-Max-Heap # Vedligeholdelse af algoritmen Bemærk at Undergrenen af den i te knude, er altid nummereret højere end i Undergrenen af den i te knude er altid en rod i en max-heap! Ved start af loop (markeret med blå) er max-heap egenskab opretholdt for undergrene Ved udløb, er det samme gældende nu også fra i 4 4 0 4 5 6 9 0 4 5 4 6 9 4 8 9 0 8 9 0 8 7 8 7 () () 8
Bevis for korrekthed af Build-Max-Heap # Terminering: Når i = 0 skal samtlige knudepunkter iflg. Loop invarianten være rod for et max-heap 6 4 0 4 5 8 7 9 8 9 0 4 9
Udførselstid for Build-Max-heap Som sagt, udførslen af max-heapify er O(log (n)) Max-heapify bliver kaldt O(n) gange, og dermed får vi en øvre grænse for vores kompleksitet på O(nLog (n)) Men, vi kan gøre det bedre! En n-element heap har højden h = Log (n) og allerhøst n/ h+ knuder Tiden for max-heapify kan også skrives som O(h), og så kan vi skrive den samlede tidsmæssige pris for udførslen af algoritmen (på tavlen) Dermed har vi en kompleksitet på O(n) (men den falder selvfølgelig også under O(nLog (n)). 0
Heap sort algoritmen! Endelig Pudsigt nok bygger heap sort på Build-Max-Heap Max-Heapify Algoritmen baserer sig på udskiftning mellem øverste og nederste element og derefter re-etablering af heap egenskabet Heap-sort(A) Build-max-heap(A) Heap sort er en meget anvendt algoritme, bl.a. til prioritets køer som vi ser nærmeret på lidt senere For i = length(a) downto do exchange A[] = A[i] 4 5 heap-size[a] = heap-size[a] Max-Heapify (A, )
Heap sort grafisk gennemgang 6 4 0 6 4 0 8 7 9 4 4 5 8 7 9 8 9 0 4 4 8 0 Udgangspunkt efter Build-Max-Heapify 4 5 4 7 9 8 9 0 6
Heap sort grafisk gennemgang 0 8 9 4 5 4 7 8 9 0 9 4 6 8 4 5 4 7 8 9 0 0 4 6
Heap sort grafisk gennemgang 8 7 4 5 4 9 8 9 0 7 0 4 6 4 4 5 8 9 8 9 0 0 4 6 4
Heap sort grafisk gennemgang 4 4 5 7 8 9 8 9 0 0 4 6 4 5 4 7 8 9 8 9 0 0 4 6 5
Heap sort grafisk gennemgang 4 5 4 7 8 9 8 9 0 0 4 6 4 5 4 7 8 9 4 7 8 9 0 4 6 8 9 0 0 4 6 6
Heap sort - køretid Heap sort proceduren tager O(nLog(n)) Build-Max-Heap(n) = O(n) Max-Heapify(n) = O(Log(n)) (kaldes n- gange) Sammenlign med Quicksort der tager O(n ) Der dog i gennemsnit, O(nLog(n)), har en bedre tid end heap sort Og med merge-sort Θ(nLog(n)) Der dog kræver Ω(n) lager plads mod O() lager plads for heap sort En hybrid af quicksort og heap sort blev udviklet i 997 Algoritmen starter med quick sort og ved en hvis størrelse af rekursivitetsdybden skifter den til heap sort Algoritmen udnytter dermed de bedste egenskaber af heap sort og quick sort 7
Eksempel på anvendelse: Prioritets køer En prioritetskø er en datastruktur til vedligeholdelse af et sæt af elementer, hver med en tilknyttet værdi kaldet en nøgle Prioritetskøer anvendes bl.a. Planlægning af jobs i et operativ system Håndtering af data trafik Diskrete event simulatorer Effektiv søgning af korteste sti i en vægtet graf, f.eks. A* algoritmen. Prioritetskøen indeholder, efter prioritet, lovende løsninger der skal efterprøves. 6. 4 0 4 8 5 7 9 8 9 0 4 8
Hvorfor anvende heaps for prioritets køer? Linked List Binary Tree (Min-)Heap Fibonacci Heap Insert O() O(log n) O(log n) O() Accessmin O(n) O() O() O() Deletemin O(n) O(log n) O(log n) O(log n)* Decreasekey O() O(log n) O(log n) O()* Delete O(n) O(n) O(log n) O(log n)* Merge O() O(m log(n+m)) O(m log(n+m)) O() * værste gennemsnitstid 9
Dagsorden Heap sort Hvad er en heap? Basale heap operationer Vedligeholdelse af heap egenskabet under sortering Gennemgang af heap sort via eksempel Anvendelse af heap sort: Prioritetskøer Quick sort Virkemåde Partitionering af array Ydelse af quick sort Effektivisering vha. randomiseret input Opsummering og konklusion Opgaver 0
Quick sort Del-og-hersk type sorteringsalgoritme Del: Opdel arrayet A[p..r] i to del-arrays (potentielt tomme) A = A[p..q-] og A = A[q+..r], således A A[q] A Bemærk det er nødvendigt at finde q som en del af denne process Hersk: Sorter de to del-array ved et rekursivt kald til quicksort Kombiner: Eftersom de sorterede del-arrays er sorteret ved returnering, er kombinering nem: hele arrayet A = [A A ] er sorteret. QUICKSORT (A, p, r) If p < r then q = Partition (A, p, r) Quicksort(A, p, q ) 4 Quicksort(A, q +, r)
Partitionering af arrayet Nøglen i algoritmen ligger i at dele arrayet op på en smart måde x x > x ubegrænset Valg af et pivot punkt, x, hvormed data bliver sorteret i de respektive områder PARTITION (A, p, r) x = A[r] I = p For j = p to (r ) 4 do if A[j] x 5 then i = i + 6 exchange A[i] A[j] 7 exchange A[i+] A[r] 8 Return i +
To tilfælde af iterationer Hvis A[j] > x >x x x > x x Hvis A[j] X x > x x x x > x x x > x
Eksempel på partitionering af et array 8 7 5 6 4 8 7 5 6 4 8 7 5 6 4 8 7 5 6 4 8 7 5 6 4 8 7 5 6 4 8 7 5 6 4 4 7 5 6 8 7 8 5 6 4 4
Ydelsen af Quicksort Værste tilfælde Sker når rutinen deler et problem op i et med hhv. n og 0 elementer Antag dette sker i hvert rekursivt kald T(0) = Θ() T(n) = T(n ) + T(0) + Θ(n) = T(n ) + Θ(n) = Θ(n ) Bedste tilfælde Bedste tilfælde sker når problemet deles op i maksimalt n/ elementer Antag dette sker i hver rekursivt kald T(n) T(n/) + Θ(n) = O(nLog (n)) 5
Gennemsnitsydelsen af quicksort Påstand: Gennemsnitsydelsen er tættere på bedste tilfælde, end på værste tilfælde n cn (/0)n (9/0)n cn Log 0/9 (n) Log 0 (n) (/00)n (9/00)n (9/00)n (8/00)n cn cn T ( n) T (9n /0) + T ( n /0) + cn cn O(nLog(n)) 6
Randomiseret version af quicksort Ydelsesanalysen er baseret på at alle permutationer af input muligheder sker med lige stor sandsynlighed I virkelighedens verden er dette oftest ikke tilfældet! Modificering af partitioneringsalgoritmen til RANDOM-PARTITION (A, p, r) i = Random(p, r) Exchange A[r] with A[i] Return Partition (A, p, r) Ideen er at vælge pivot punktet x tilfældigt, i stedet for altid at vælge x = A[r] (det sidste element i input arrayet) 7
Ydelse for randomiseret quicksort For værste tilfælde T ( n) = Max = Θ( n I gennemsnit bliver det 0 q n max( cq cn cn ( T ( q) + T ( n q )) + Θ( n) c(n ) + Θ( n) ) + c( n q ) T ( n) = O( nlog( n)) ) + Θ( n) 8
Det var så det, eller.??? 9
Dagsorden Heap sort Hvad er en heap? Basale heap operationer Vedligeholdelse af heap egenskabet under sortering Gennemgang af heap sort via eksempel Anvendelse af heap sort: Prioritetskøer Quick sort Virkemåde Partitionering af array Ydelse af quick sort Effektivisering vha. randomiseret input Opsummering og konklusion Opgaver 40
Opsummering og konklusion Heap sort 4
Dagsorden Heap sort Hvad er en heap? Basale heap operationer Vedligeholdelse af heap egenskabet under sortering Gennemgang af heap sort via eksempel Anvendelse af heap sort: Prioritetskøer Quick sort Virkemåde Partitionering af array Ydelse af quick sort Effektivisering vha. randomiseret input Opsummering og konklusion Opgaver 4
Opgaver Redegør for hvorfor den største undergren i en heap er n/ (slide ) Lav en implementering af en, eller begge af de nævnte algoritmer og prøv at måle tider på udførsel af algoritmerne Prøv at lave meget store arrays (f.eks. Ved brug af tilfældighedsgenerator til generering af data til test) Formål: at få en praktisk fornemmelse for algoritme kompleksitet Øvelse 6.4-, 6.4-, Øvelse 6.5- Øvelse 7.-4 4