Grundlagen der Algorithmen und Datenstrukturen Kapitel 5 Prof. Dr. Christian Scheideler (Stv: Stefan Schmid) SS 2008 06.11.2015 Kapitel 5 1 Ein paar Infos vorweg... - Kapitel 0-4 sind relevant für Klausur (also inkl. Hashing)! - Notenbonus der Uebungen gilt nicht, falls Prüfung nicht bestanden. - Gesamtnote = 50% Mid + 50% End - Probeprüfung auf Web (Lösung?) - Mitnehmen: Handschriftliches DIN A4 Blatt 06.11.2015 Kapitel 5 2 06.11.2015 Kapitel 5 3 Wörterbuch S: Menge von Elementen Jedes Element e identifiziert über key(e). Operationen: • S.insert(e: Element): S:=S [ {e} • S.remove(k: Key): S:=Sn{e}, wobei e das Element ist mit key(e)=k • S.find(k: Key): Falls es ein e2 S gibt mit key(e)=k, dann gib e aus, sonst gib ? aus 06.11.2015 Kapitel 5 4 Statisches Wörterbuch Lösungsmöglichkeiten: • Perfektes Hashing 1 – Vorteil: Suche in konstanter Zeit – Nachteil: keine Ordnung auf Elementen, d.h. Bereichsanfragen (alle Namen, die mit A anfangen) teuer 3 14 5 5 10 14 19 3 19 1 10 • Speicherung der Daten in sortiertem Feld 1 3 5 10 14 19 Wie geht das? – Vorteil: Bereichsanfragen möglich – Nachteil: Suche teurer (logarithmische Zeit) 06.11.2015 Kapitel 5 5 Wieso Sortieren? • Telefonbuch ohne Sortierung nach Namen? • Beispiel aus dem Skript: Statistik bei Volkszählung – Bei der US Volkzählung 1880 benötigten 1500 Leute 7 Jahre um die Daten zu zählen und ordnen – Herman Hollerith baute darauf hin Sortiermaschinen, welche die Bearbeitungszeit der nächsten Zählung trotz grösserer Population auf 1 Jahr reduzierte. – Ursprung von IBM – Sortieren (Pre-processing) hilft vielerlei Fragen effizient zu beantworten: e.g., finde alle Personen zw. 20 und 30 die auf einem Bauernhof leben 06.11.2015 Kapitel 5 6 Sortierproblem • Eingabe: Sequenz s = <e1,…,en> mit Ordnung <= auf den Schlüsseln key(ei) (Beispiel: 5 10 19 1 14 3 ) • Ausgabe: Sequenz s´ = <e´1,…,e´n>, so dass key(ei)<=key(ei+1) für alle 1<=i<n und s´ eine Permutation von s ist (Beispiel: 1 3 5 10 14 19 ) 06.11.2015 Kapitel 5 7 Ordnungen • Ordnung auf Zahlen: klar • Ordnung auf Vektoren: z.B. Länge des Vektors • Ordnung auf Namen: lexikographische Ordnung (erst alle Namen, die mit A beginnen, dann B, usw.) 06.11.2015 Kapitel 5 8 Einfache Sortierverfahren Selection Sort: nimm wiederholt das kleinste Element aus der Eingabesequenz, lösche es, und hänge es an das Ende der Ausgabesequenz an. Beispiel: 06.11.2015 <4,7,1,1> | <> ! <4,7,1> | <1> ! <4,7> | <1,1> ! <7> | <1,1,4> ! <> | <1,1,4,7> Kapitel 5 9 Einfache Sortierverfahren Selection Sort: nimm wiederholt das kleinste Element aus der Eingabesequenz, lösche es, und hänge es an das Ende der Ausgabesequenz an. Zeitaufwand (worst case): • Minimumsuche in Feld der Größe i: (i) • Gesamtzeit: i=1..n (i) = (n2) 06.11.2015 Kapitel 5 10 Selection Sort Procedure SelectionSort(a: Array [1..n] of Element) for i:=1 to n-1 do // bewege min{a[i],…,a[n]} nach a[i] for j:=i+1 to n do if a[i]>a[j] then a[i] $ a[j] Vorteil: sehr einfach zu implementieren (1 Array reicht!), also gut für kurze Sequenzen Nachteil: kann für lange Sequenzen lange dauern 06.11.2015 Kapitel 5 11 Selection Sort: Beispiel i j 5 10 19 1 3 14 j Element grösser => weiter Prinzip: Suche Minimum im Feld rechts von i und füge es bei i ein. (Ausgabesequenz = vorne am Array) Laufe ganzes Feld nach rechts durch, swappe mit i-Position wann immer ein neuer Rekord! 06.11.2015 Kapitel 5 12 Selection Sort: Beispiel i 5 j 10 19 1 3 14 j Element grösser => weiter 06.11.2015 Kapitel 5 13 Selection Sort: Beispiel i 5 j 10 19 1 3 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 14 Selection Sort: Beispiel i 1 j 10 19 5 3 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 15 Selection Sort: Beispiel i 1 j 10 19 5 3 14 j Element grösser => weiter! 06.11.2015 Kapitel 5 16 Selection Sort: Beispiel i 1 j 10 19 5 3 14 j Element grösser => i++; j=i+1! 06.11.2015 Kapitel 5 17 Selection Sort: Beispiel 1 i j 10 19 5 3 14 j Element grösser => weiter 06.11.2015 Kapitel 5 18 Selection Sort: Beispiel i 1 10 j 19 5 3 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 19 Selection Sort: Beispiel i 1 5 j 19 10 3 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 20 Selection Sort: Beispiel i 1 5 j 19 10 3 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 21 Selection Sort: Beispiel i 1 3 j 19 10 5 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 22 Selection Sort: Beispiel i 1 3 j 19 10 5 14 j Element grösser => i++; j=i+1! 06.11.2015 Kapitel 5 23 Selection Sort: Beispiel 1 3 i j 19 10 5 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 24 Selection Sort: Beispiel 1 3 i j 10 19 5 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 25 Selection Sort: Beispiel i 1 3 j 10 19 5 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 26 Selection Sort: Beispiel i 1 3 j 5 19 10 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 27 Selection Sort: Beispiel i 1 3 j 5 19 10 14 j Element grösser => i++; j=i+1! 06.11.2015 Kapitel 5 28 Selection Sort: Beispiel 1 3 5 i j 19 10 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 29 Selection Sort: Beispiel i 1 3 5 10 j 19 14 j Element grösser => i++; j:=i+1! 06.11.2015 Kapitel 5 30 Selection Sort: Beispiel 1 3 5 10 i j 19 14 j Element kleiner => swap! 06.11.2015 Kapitel 5 31 Selection Sort: Beispiel 1 3 5 10 i j 14 19 Fertig! 06.11.2015 Kapitel 5 32 Einfache Sortierverfahren Insertion Sort: nimm Element für Element aus der Eingabesequenz und füge es in der richtigen Position der Ausgabesequenz ein Beispiel: 06.11.2015 <4,7,1,1> | <> ! <7,1,1> | <4> ! <1,1> | <4,7> ! <1> | <1,4,7> ! <> | <1,1,4,7> Kapitel 5 33 Einfache Sortierverfahren Insertion Sort: nimm Element für Element aus der Eingabesequenz und füge es in der richtigen Position der Ausgabesequenz ein Zeitaufwand (worst case): • Einfügung an richtiger Stelle beim i-ten Element: O(i) (wegen Verschiebungen) • Gesamtaufwand: i=1..n O(i) = O(n2) Wieso O()? 06.11.2015 Kapitel 5 34 Insertion Sort Procedure InsertionSort(a: Array [1..n] of Element) for i:=2 to n do // bewege a[i] zum richtigen Platz „runterblubbern“ for j:=i-1 downto 1 do if a[j]>a[j+1] then a[j] $ a[j+1] Vorteil: sehr einfach zu implementieren (1 Array genügt auch hier), also gut für kurze Sequenzen Nachteil: kann für lange Sequenzen lange dauern 06.11.2015 Kapitel 5 35 Beispiel (Wikipedia...) 06.11.2015 Kapitel 5 36 Insertion Sort: Beispiel j i 5 10 19 1 3 14 j Element kleiner als j+1 Element => weiter Prinzip: Für immer grössere i, lasse i-tes Element „runterblubbern“, soweit bis Nachfolger kleiner => alles links von i ist sortiert! (Ausgabesequenz = vorne am Array) Laufe Feld nach links durch soweit wie nötig, swappe mit Nachbarposition wann immer ein neuer Rekord! 06.11.2015 Kapitel 5 37 Insertion Sort: Beispiel 5 j i 10 19 1 3 14 j Element kleiner als j+1 Element => weiter 06.11.2015 Kapitel 5 38 Insertion Sort: Beispiel j 5 i 10 19 1 3 14 j Element kleiner als j+1 Element => weiter 06.11.2015 Kapitel 5 39 Insertion Sort: Beispiel 5 10 j i 19 1 3 14 j Element grösser => swap 06.11.2015 Kapitel 5 40 Insertion Sort: Beispiel 5 10 j i 1 19 3 14 j Element grösser => swap 06.11.2015 Kapitel 5 41 Insertion Sort: Beispiel j 5 1 i 10 19 3 14 j Element grösser als (j+1) Element => swap 06.11.2015 Kapitel 5 42 Insertion Sort: Beispiel j 5 i 1 10 19 3 14 j Element grösser als (j+1) Element => swap 06.11.2015 Kapitel 5 43 Insertion Sort: Beispiel j 1 i 5 10 19 3 14 j Element grösser als (j+1) Element => swap Die 1 ist ganz „runtergeblubbert“! 06.11.2015 Kapitel 5 44 Insertion Sort: Beispiel 1 5 10 j i 19 3 14 j Element grösser als (j+1) Element => swap 06.11.2015 Kapitel 5 45 Insertion Sort: Beispiel j 1 5 10 i 3 19 14 j Element grösser als (j+1) Element => swap 06.11.2015 Kapitel 5 46 Insertion Sort: Beispiel j 1 5 i 3 10 19 14 j Element grösser als (j+1) Element => swap 06.11.2015 Kapitel 5 47 Insertion Sort: Beispiel j 1 i 3 5 10 19 14 j Element kleiner als (j+1) Element => weiter Die 3 „blubberte“ nur an zweitunterste Stelle. 06.11.2015 Kapitel 5 48 Insertion Sort: Beispiel j 1 3 5 10 19 i 14 j Element grösser als (j+1) Element => swap Die 14 „blubbert“ nur eine Stelle weit. 06.11.2015 Kapitel 5 49 Insertion Sort: Beispiel j 1 06.11.2015 3 5 10 Kapitel 5 i 14 19 50 Insertion Sort: Beispiel j 1 3 5 10 i 14 19 Rest ok, alles schon sortiert gegen links => fertig! 06.11.2015 Kapitel 5 51 Einfache Sortierverfahren Selection Sort: • Mit besserer Minimumstrategie worst-case Laufzeit O(n log n) erreichbar (mehr dazu in Kapitel 6) Insertion Sort: • Mit besserer Einfügestrategie (lass Lücken) worst-case Laufzeit O(n log2 n) erreichbar 06.11.2015 Kapitel 5 52 Mergesort Idee: zerlege Sortierproblem rekursiv in Teilprobleme, die separat sortiert werden und dann verschmolzen werden 10 5 19 1 14 3 5 10 19 1 3 14 1 3 5 10 14 19 rekursiv merge 06.11.2015 Kapitel 5 53 Beispiel (Wikipedia) 06.11.2015 Kapitel 5 54 Mergesort Procedure Mergesort(l,r: Integer) // a[l..r]: zu sortierendes Feld if l=r then return // fertig m:= b(r+l)/2c // Mitte Mergesort(l,m) Mergesort(m+1,r) j:=l; k:=m+1 for i:=1 to r-l+1 do // verwende Hilfsfeld b zum mergen if j>m then b[i]:=a[k]; k:=k+1 Erstes Feld schon leer! else if k>r then b[i]:=a[j]; j:=j+1 Zweites Feld schon leer! else if a[j]<a[k] then b[i]:=a[j]; j:=j+1 else b[i]:=a[k]; k:=k+1 for i:=1 to r-l+1 do a[l-1+i]:=b[i] 06.11.2015 Kapitel 5 55 Zwei sortierte Felder mergen j k m 5 10 19 1 3 14 merge 06.11.2015 Kapitel 5 56 Zwei sortierte Felder mergen 5 10 19 1 3 14 merge 1 06.11.2015 Kapitel 5 57 Zwei sortierte Felder mergen 5 10 19 1 3 14 merge 1 06.11.2015 Kapitel 5 58 Zwei sortierte Felder mergen 5 10 1 3 19 1 3 14 merge 06.11.2015 Kapitel 5 59 Zwei sortierte Felder mergen 5 10 1 3 19 1 3 14 merge 06.11.2015 Kapitel 5 60 Zwei sortierte Felder mergen 5 10 19 1 3 5 1 3 14 merge 06.11.2015 Kapitel 5 61 Zwei sortierte Felder mergen 5 10 19 1 3 5 1 3 14 merge 06.11.2015 Kapitel 5 62 Zwei sortierte Felder mergen 5 10 19 1 1 3 5 10 3 14 merge 06.11.2015 Kapitel 5 63 Zwei sortierte Felder mergen 5 10 19 1 1 3 5 10 3 14 merge 06.11.2015 Kapitel 5 64 Zwei sortierte Felder mergen 5 10 19 1 3 1 3 5 10 14 14 merge 06.11.2015 Kapitel 5 65 Zwei sortierte Felder mergen 5 10 19 1 3 1 3 5 10 14 14 merge 06.11.2015 Kapitel 5 66 Zwei sortierte Felder mergen 5 10 19 1 3 14 1 3 5 10 14 19 merge 06.11.2015 Kapitel 5 67 Zwei sortierte Felder mergen 5 10 19 1 3 14 1 3 5 10 14 19 merge 06.11.2015 Kapitel 5 68 Mergesort Theorem 5.2: Mergesort benötigt O(n log n) Zeit, um eine Folge der Länge n zu sortieren. Beweis: • T(n): Laufzeit bei Folgenlänge n • T(1) = (1) und T(n) = T(bn/2c) + T(dn/2e) + (n) • aus Übungsaufgabe: T(n)=O(n log n) 06.11.2015 Kapitel 5 69 Untere Schranke Ziel einer unteren Laufzeitschranke t(n): Zeige, dass kein Algorithmus (aus einer gewissen Klasse) eine bessere Laufzeit als O(t(n)) im worst case haben kann. Methodik: nutze strukturelle Eigenschaften des Problems Beispiel: vergleichsbasiertes Sortieren 06.11.2015 Kapitel 5 70 Untere Schranke Vergleichsbasiertes Sortieren: Wie oft muss jeder vergleichsbasierte Algo im worst case einen Vergleich e<e´ machen? Frage: Gegeben sei beliebige Menge S von n Elementen. Wieviele Möglichkeiten gibt es, S als Folge darzustellen? Antwort: n! = n¢(n-1)¢(n-2)…2¢1 viele 06.11.2015 Kapitel 5 71 Untere Schranke Permutation der Eingabefolge: • Menge S: 1 3 5 14 19 • Eingabefolge: 10 06.11.2015 10 5 Kapitel 5 19 1 14 3 72 Untere Schranke Wenn der Algorithmus sortieren kann, kann er auch die Permutation ausgeben (u.u.). 1 3 5 10 14 19 10 06.11.2015 5 19 1 Kapitel 5 14 3 73 Untere Schranke Beliebiger vergleichsbasierter Algo als Entscheidungsbaum: = Menge aller Permutationen = 1 [ 2 e1<e2? ja Zeit nein 1 e3<e4? 2 e5<e6? i : Permutationsmenge, die Bedingungen bis dahin erfüllt 06.11.2015 Kapitel 5 74 Untere Schranke Beliebiger vergleichsbasierter Algo als Entscheidungsbaum: 1 1 = 2 [ 3 e1<e2? ja Zeit nein 2 e3<e4? 3 e5<e6? i : Permutationsmenge, die Bedingungen bis dahin erfüllt 06.11.2015 Kapitel 5 75 Untere Schranke Beliebiger vergleichsbasierter Algo als Entscheidungsbaum: = {1, 2} e1<e2? ja Zeit nein 1 1 2 2 i : eindeutige Permutation der Eingabefolge 06.11.2015 Kapitel 5 76 Untere Schranke Beliebiger vergleichsbasierter Algo als Entscheidungsbaum: = {1, 2} e1<e2? ja Zeit nein 1 1 2 2 Wieviele Blätter muss Entscheidungsbaum haben? 06.11.2015 Kapitel 5 77 Untere Schranke Beliebiger vergleichsbasierter Algo als Entscheidungsbaum: = {1, 2} e1<e2? ja Zeit nein 1 2 1 06.11.2015 Mindestens n! viele Blätter! Kapitel 5 2 78 Untere Schranke Beliebiger vergleichsbasierter Algo als Entscheidungsbaum: Baum der Tiefe T: Höchstens 2T Blätter Zeit 2T >= n! , T >= log(n!) = (n log n) e.g., O() folgt aus n! ¸ (n/e)n Jeder vergleichsbasierte Algo hat (n log n) Laufzeit 06.11.2015 Kapitel 5 79 Beispiel Ein Algo für Arrays der Grösse 3: {(123),(132),(213),(231),(312),(321)} Position 1 < Position 2 {(123),(132),(231)} Position 2 < Position 1 {(213), (312),(321)} p2 < p3? {(123)} p1 < p3? 06.11.2015 { (132),(231)} { (132)} ... Um (132) zu sortieren braucht dieser Algo 3 Vergleiche! [log(3!) = 2.58...] {(231)} Kapitel 5 80 Quicksort Idee: ähnlich wie Mergesort, aber Aufspaltung in Teilfolgen nicht in Mitte sondern nach speziellem Pivotelement 10 5 19 1 14 3 5 1 3 10 19 14 1 3 5 10 14 19 unsortiert! ordne nach <10 und >10 rekursiv 06.11.2015 Kapitel 5 81 Quicksort Procedure Quicksort(l,r: Integer) // a[l..r]: zu sortierendes Feld if r>l then v:=a[r]; i:=l-1; j:=r repeat // ordne Elemente nach Pivot v repeat i:=i+1 until a[i]>=v repeat j:=j-1 until a[j]<=v if i<j then a[i] $ a[j] until j<=i a[i] $ a[r] Quicksort(l,i-1) // sortiere linke Teilfolge Quicksort(i+1,r) // sortiere rechte Teilfolge 06.11.2015 Kapitel 5 82 Quicksort: Quicksort i: gehe solange nach links bis grösser als Pivot j: gehe solange nach rechts bis kleiner als Pivot => dann mache swap! 06.11.2015 Kapitel 5 Jetzt rekursiv beide Hälften mit QS! 83 Quicksort: Beispiel j i Pivot! 5 10 19 1 3 14 i++, dann i: gehe solange nach rechts bis >= Pivot j--, dann j: gehe solange nach links bis <= Pivot 06.11.2015 Kapitel 5 84 Quicksort: Beispiel j i Pivot! 5 10 19 1 3 14 i<j => ok => swap! 06.11.2015 Kapitel 5 85 Quicksort: Beispiel j i Pivot! 5 10 3 1 19 14 i++ solange bis >= Pivot j-- solange bis <= Pivot 06.11.2015 Kapitel 5 86 Quicksort: Beispiel j i Pivot! 5 10 3 1 19 14 i<j : falsch => kein swap mehr! Nun noch Pivos an Position i swappen! 06.11.2015 Kapitel 5 87 Quicksort: Beispiel Pivot ist an richtiger sortierter Position! Wird nicht mehr ändern! 5 10 3 1 Sortiere rekursiv! 06.11.2015 Kapitel 5 14 19 Sortiere rekursiv! 88 Quicksort Problem: im worst case kann Quicksort (n2) Laufzeit haben (wenn schon sortiert) Lösungen: • wähle zufälliges Pivotelement (Laufzeit O(n log n) mit hoher W.keit) • berechne Median (Element in Mitte) ! dafür Selektionsalgorithmus (Kap 5.5) 06.11.2015 Kapitel 5 89 Quicksort: Worst-Case Pivot 1 1 3 5 10 14 19 Sortiere rekursiv! 06.11.2015 Kapitel 5 90 Quicksort: Worst-Case Pivot 2 1 3 5 10 14 19 Sortiere rekursiv! 06.11.2015 Kapitel 5 91 Quicksort: Worst-Case Pivot 3 1 3 5 10 14 19 Sortiere rekursiv! 06.11.2015 Kapitel 5 92 Quicksort: Worst-Case Pivot 3 1 3 5 10 14 19 Insgesamt n Rekursionen, jede Rekursion erfordert I (für i=1..n) Vergleiche mit Pivotelement => O(n2) 06.11.2015 Kapitel 5 93 Quicksort Laufzeit bei zufälligem Pivot-Element: • Zähle Anzahl Vergleiche (Rest macht nur konstanten Faktor aus) • C(n): erwartete Anzahl Vergleiche bei n Elementen Theorem 5.6: C(n) <= 2n ln n <= 1.4 n log n 06.11.2015 Kapitel 5 94 Beweis von Theorem 5.6 • s=<e1,…,en>: sortierte Sequenz 10 5 19 1 14 3 5 1 3 10 19 14 ordne nach <10 und >10 • Quicksort: nur Vergleiche mit Pivotelement, Pivotelement nicht im rekursivem Aufruf • ei und ej werden <=1-mal verglichen und nur, wenn ei oder ej Pivotelement ist 06.11.2015 Kapitel 5 95 Beweis von Theorem 5.6 • Zufallsvariable Xi,j 2 {0,1} • Xi,j = 1 , ei und ej werden verglichen C(n) = E[i<j Xi,j] = i<j E[Xi,j] = i<j Pr[Xi,j = 1] Lemma 5.7: Pr[Xi,j] = 2/(j-i+1) 06.11.2015 Kapitel 5 96 Beweis von Theorem 5.6 Lemma 5.7: Pr[Xi,j] = 2/(j-i+1) Beweis: • M={ei,…,ej} • Irgendwann wird Element aus M als Pivot ausgewählt (bis dahin bleibt M zusammen) • ei und ej werden nur verglichen, wenn ei oder ej als Pivot ausgewählt werden • Pr[ei oder ej in M ausgewählt]=2/|M| 06.11.2015 Kapitel 5 97 Beweis von Theorem 5.6 C(n) = i<j Pr[Xi,j=1] = i<j 2/(j-i+1) = i=1n k=2n-i+1 2/k <= i=1n k=2n 2/k = 2n k=2n 1/k <= 2n ln n Erwartungsgemäß ist Quicksort also sehr effizient (bestätigt Praxis). 06.11.2015 Kapitel 5 98 Harmonic Number Es gilt: Hn · ln n + 1 06.11.2015 Kapitel 5 99 Selektion Problem: finde k-kleinstes Element in einer Folge von n Elementen Lösung: sortiere Elemente, gib k-tes Element aus ! Zeit O(n log n) Geht das auch schneller?? 06.11.2015 Kapitel 5 100 Selektion Ansatz: verfahre ähnlich zu Quicksort 10 5 19 1 14 3 5 1 3 10 19 14 • j: Position des Pivotelements • k<j: mach mit linker Teilfolge weiter • k>j: mach mit rechter Teilfolge weiter 06.11.2015 Kapitel 5 101 Selektion Function Quickselect(l,r,k: Integer): Element // a[l..r]: Restfeld, k: k-kleinstes Element if r=l then return a[l] z:=zufällige Position in {l,..,r}; a[z] $ a[r] v:=a[r]; i:=l-1; j:=r repeat // ordne Elemente nach Pivot v repeat i:=i+1 until a[i]>=v repeat j:=j-1 until a[j]<=v if i<j then a[i] $ a[j] until j<=i a[i] $ a[r] if k<i then e:=Quickselect(l,i-1,k) if k>i then e:=Quickselect(i+1,r,k) if k=i then e:=a[k] return e 06.11.2015 Kapitel 5 102 Quickselect • C(n): erwartete Anzahl Vergleiche Theorem 5.8: C(n)=O(n) Beweis: • Pivot ist gut: keine der Teilfolgen länger als 2n/3 • Sei p=Pr[Pivot ist gut] gut • p=1/3 06.11.2015 1/3 2/3 Kapitel 5 103 Quickselect • Pivot gut: Restaufwand <= C(2n/3) • Pivot schlecht: Restaufwand <= C(n) C(n) <= n + p C(2n/3) + (1-p) C(n) , C(n) <= n/p + C(2n/3) <= 3n + C(2n/3) <= 3(n+2n/3+4n/9+…) <= 3n i>=0 (2/3)i <= 3n / (1-2/3) = 9n 06.11.2015 Kapitel 5 104 Soweit gekommen am Dienstag. Start hier am Donnerstag! 06.11.2015 Kapitel 5 105 Ein paar Infos vorweg... • Morgen Freitag: 15:00-16:30 Fragestunde von Prof. Scheideler im FMI HS 2 (Fragen zur Vorlesung bis jetzt) • Heute: - kurze Repetition von Quicksort - Noch schnellere Sortieralgorithmen! - Externes sortieren (was wenn nicht genug Speicher vorhanden für ganzes Feld?) - Ev. noch was zur Analyse von While Schleifen 06.11.2015 Kapitel 5 106 Repetition (1) • Wie kann man etwas effizient sortieren? • Gesehen: „Minimum-Selektion “-Algo O(n2), „Einfüge“Algo O(n2), Algo durch „rekursives Mergen“ O(n log n), Quicksort Algo O(n2) • Wieso ist Mergesort immer O(n log n) während Quicksort zum Teil O(n2) ist? • Bei Quicksort können die beiden rekursiv zu bearbeitenden Teile unterschiedlich gross sein... 06.11.2015 Kapitel 5 107 Repetition (2) Weshalb ist es schlecht, wenn die Teile unterschiedlich gross sind? (Weshalb wird Quicksort dennoch verwendet in der Praxis?) 06.11.2015 Kapitel 5 108 Repetition (3) Rekursion: Wie wird das z.B. ausgeführt? Procedure Quicksort(l,r: Integer) // a[l..r]: zu sortierendes Feld if r>l then v:=a[r]; i:=l-1; j:=r repeat // ordne Elemente nach Pivot v repeat i:=i+1 until a[i]>=v repeat j:=j-1 until a[j]<=v if i<j then a[i] $ a[j] until j<=i a[i] $ a[r] Quicksort(l,i-1) // sortiere linke Teilfolge Quicksort(i+1,r) // sortiere rechte Teilfolge 06.11.2015 Kapitel 5 109 Repetition (4) j i Pivot! 5 10 19 1 3 14 i++, dann i: gehe solange nach rechts bis >= Pivot j--, dann j: gehe solange nach links bis <= Pivot 06.11.2015 Kapitel 5 110 Repetition (4) j i Pivot! 5 10 19 1 3 14 i<j => ok => swap! 06.11.2015 Kapitel 5 111 Repetition (4) j i Pivot! 5 10 3 1 19 14 i++ solange bis >= Pivot j-- solange bis <= Pivot 06.11.2015 Kapitel 5 112 Repetition (4) j i Pivot! 5 10 3 1 19 14 i<j : falsch => kein swap mehr! Nun noch Pivos an Position i swappen! 06.11.2015 Kapitel 5 113 Repetition (4) Pivot ist an richtiger sortierter Position! Wird nicht mehr ändern! 5 10 3 1 Sortiere rekursiv! 06.11.2015 Kapitel 5 14 19 Sortiere rekursiv! 114 Veranschaulichung (1) Falls Pivot immer in der Mitte: O(log (n)) viele Stufen ... Wieviele Vergleiche sind nötig pro Stufe? 06.11.2015 Kapitel 5 115 Veranschaulichung (2) Falls Pivot immer in der Mitte: n-1 Vergleiche mit Pivot ~ 2 * n/2 Vergleiche mit Pivots ~ 4 * n/4 Vergleiche mit Pivots ... Tiefe i: 2^i Subarrays der Grösse n/2^i. Bereits fixierte Pivots: 1+2+4+...+2^i. 06.11.2015 Kapitel 5 116 Veranschaulichung (2) Falls Pivot immer am Rand landet: n-1 Vergleiche mit Pivot n-2 Vergleiche mit Pivot n-3 Vergleiche mit Pivot ... Auch auf jeder Stufe ca. n Vergleiche! Was ist der Unterschied?? 06.11.2015 Kapitel 5 117 Veranschaulichung (3) Falls Pivot immer am Rand landet: O(n) Stufen -- nur ein neues fixes Element pro Stufe! ... Tiefe i: 1 Subarray der Grösse n-i. Bereits fixierte Pivots: i. 06.11.2015 Kapitel 5 118 Repetition (5) • Wieviele Vergleiche braucht ein Algorithmus im Jahr 2050 mindestens um ein Feld der Grösse n zu sortieren? • Konzept der „unteren Schranke“ oder „lower bound“ • Lösung: mind. log(n!) 06.11.2015 Kapitel 5 119 Repetition (6) • Kann man nicht schneller sortieren? • Doch – falls Algorithmus nicht vergleichsbasiert ist oder das Problem / der Input eine spezielle Form hat! Z.B.: Algorithmus der nicht nur Keys als ganzes miteinander vergleicht, sondern die Repräsentation als einzelne Ziffern berücksichtigt! Oder: Felder die nur aus ganz wenigen sich wiederholenden Keys bestehen. 06.11.2015 Kapitel 5 120 Sortieren schneller als O(n log n) • Annahme: n Elemente im Bereich {0,…,K-1} • Strategie: verwende Feld von K Listenzeigern 3 0 1 3 2 4 3 4 2 Beispiel mit n = 9, K=5 0 06.11.2015 1 2 Kapitel 5 3 4 121 Sortieren schneller als O(n log n) Procedure KSort(s: Sequence of Element) b: Array [0..K-1] of Sequence of Element foreach e2s do const time (e.g., linked list), hinten anhängen (Stabilität!) b[key(e)].pushBack(e) s:=concatenation of b[0],…,b[K-1] Laufzeit: O(n+K) Buckets Problem: nur gut für K=o(n log n) 06.11.2015 Kapitel 5 122 Erste Ziffer = Schlüssel Schlüsselraum {0,1,2,3} K-Sort Example s = (<3,a>, <1,b>, <2,c>, <3,d>, <0,e>, <0,f>, <3,g>, <2,h>, <1,i>) ... wird zu: b = ([<0,e>,<0,f>], [<1,b>,<1,i>], [<2,c>,<2,h>], [<3,a>,<3,d>,<3,g>]) also (<0,e>,<0,f>, <1,b>,<1,i>, <2,c>,<2,h>,<3,a>,<3,d>,<3,g>) Beachte: K-Sort ist stabil, d.h., Elemente mit gleichem Key bleiben in gleicher Reihenfolge wie in der Eingabe (wegen pushBack)! 06.11.2015 Kapitel 5 123 Radixsort Ideen: • Benutze Repräsentation der Schlüssel • K-adische Darstellung der Schlüssel • Sortiere Ziffer für Ziffer gemäß KSort • Behalte Ordnung der Teillisten bei 06.11.2015 Kapitel 5 124 Radixsort Procedure Radixsort(s: Sequence of Element) for i:=0 to d-1 do KSort(s,i) // sortiere gemäß keyi(x) // mit keyi(x) = (key(x) div Ki) mod K, // d.h. kleinste Ziffer zuerst! Laufzeit: O(d(n+K)) Falls maximale Zahlengröße O(log n), dann alle Zahlen <= nd für konstantes d. In diesem Fall Laufzeit für n Zahlen sortieren O(n). 06.11.2015 Kapitel 5 125 Radixsort Beispiel (Ziffern des Zehnersystems, K=10): 12 203 3 74 24 17 112 Ordnung nach Einerstelle: 0 06.11.2015 1 2 3 4 5 Kapitel 5 6 7 8 9 126 Radixsort Ergebnis nach Einerstelle: 12 112 203 3 74 24 17 Ordnung nach Zehnerstelle: 0 06.11.2015 1 2 3 4 5 Kapitel 5 6 7 8 9 127 Radixsort Ergebnis nach Zehnerstelle: 203 3 12 112 17 24 74 Ordnung nach Hunderterstelle: 0 1 2 3 4 5 6 7 8 9 Reihenfolge von Zahlen mit gleicher Zehnerstelle behalten wir bei! (Stabilität von k-Sort!) 06.11.2015 Kapitel 5 128 Radixsort Ergebnis nach Hunderterstelle: 3 12 17 24 Sortiert! 06.11.2015 74 112 203 Zauberei??? Kapitel 5 129 Radixsort 3135 < 3146 Korrektheit: • Für jedes Paar x,y mit key(x)<key(y) gilt: es existiert i mit keyi(x)<keyi(y) und keyj(x)=keyj(y) für alle j>i (j wächst gegen links: kleine Stellen zuerst) • Schleifendurchlauf für i: poss(x)<poss(y) (poss(z): Position von z in Folge s) • Schleifendurchlauf für j>i: Ordnung wird beibehalten wegen pushBack in KSort 06.11.2015 Kapitel 5 130 Radixsort: Beispiel Wikipedia Input Phase 1 Phase 2 Phase 3 06.11.2015 Kapitel 5 Output 131 Externes Sortieren Heutige Computer: Prozessor Interner Speicher Größe M Blockgröße B Externer Speicher 06.11.2015 Kapitel 5 132 Externes Sortieren Problem: Minimiere Blocktransfers zwischen internem und externem Speicher (# Vergleiche nun sekundär / vernachlässigbar) Lösung: verwende Mergesort für 2 sortierte Teilsequenzen O(n/B) Blocktransfers 06.11.2015 Kapitel 5 133 Zwei sortierte Felder mergen load block 5 load block m 10 19 1 3 14 merge 06.11.2015 Kapitel 5 134 Zwei sortierte Felder mergen 5 merge 10 19 1 3 14 write block 1 06.11.2015 Kapitel 5 135 Zwei sortierte Felder mergen load block 5 10 19 1 3 14 merge 1 06.11.2015 Kapitel 5 136 Zwei sortierte Felder mergen 5 10 19 merge 3 14 write block 1 06.11.2015 1 3 Kapitel 5 137 Zwei sortierte Felder mergen load block 5 10 1 3 19 1 3 14 merge 06.11.2015 Kapitel 5 138 Zwei sortierte Felder mergen 5 10 19 merge 1 3 14 write block 1 3 5 Etc. 06.11.2015 Kapitel 5 139 Externes Sortieren Externes Mergesort (einfach): • sortiere Folge in Abschnitten der Größe M (komplett intern möglich, e.g., Quicksort) M M M M M • Merge von jeweils zwei Teilfolgen bis zur Gesamtfolge (<=1+log(n/M) Durchläufe) Anzahl Blocktransfers: O(2n/B (1+log(n/M))) 06.11.2015 Kapitel 5 140 Externes Sortieren Externes Mergesort (einfach): Mergen zweier Teilfolgen mittels 3 Blöcken im internen Speicher (rote Kästen): B Merge zwei Sequenzen blockweise! Min B 06.11.2015 B Kapitel 5 M 141 Externes Sortieren Externes Mergesort (einfach): Mergen zweier Teilfolgen mittels 3 Blöcken im internen Speicher (rote Kästen): B B 06.11.2015 B Kapitel 5 M 142 Beispiel 06.11.2015 Kapitel 5 143 Externes Sortieren Externes Mergesort (verbessert): • sortiere Folge in Abschnitten der Größe M (komplett intern möglich) M M M M M • Merge von jeweils M/B-1 Teilfolgen bis zur Gesamtfolge (<=1+logM/B(n/M) Durchläufe) Anzahl Blocktransf.: O(2n/B (1+logM/B(n/M))) 06.11.2015 Kapitel 5 144 Externes Sortieren Externes Mergesort (verbessert): Mergen von M/B-1 Teilfolgen mittels M/B Blöcken im internen Speicher (rote Kästen): Min 06.11.2015 Kapitel 5 145 Externes Sortieren Externes Mergesort (verbessert): Mergen von M/B-1 Teilfolgen mittels M/B Blöcken im internen Speicher (rote Kästen): Min! 06.11.2015 Kapitel 5 146 Externes Sortieren Externes Mergesort (verbessert): Mergen von M/B-1 Teilfolgen mittels M/B Blöcken im internen Speicher (rote Kästen): Min 06.11.2015 Kapitel 5 147 Beispiel M/B-1=3 load block load block 5 10 1 19 load block 3 14 merge 06.11.2015 Kapitel 5 148 Beispiel M/B-1=3 5 merge 10 1 19 3 14 write block 1 06.11.2015 Kapitel 5 149 Beispiel M/B-1=3 read block 5 10 1 19 3 14 merge 1 06.11.2015 Kapitel 5 150 Beispiel M/B-1=3 5 10 1 19 merge 14 write block 1 06.11.2015 3 3 Kapitel 5 151 Beispiel M/B-1=3 read block 5 10 1 3 1 19 3 14 merge Etc. 06.11.2015 Kapitel 5 152 Externes Sortieren Externes Mergesort (verbessert): Mergen von M/B-1 Teilfolgen mittels M/B Blöcken im internen Speicher (rote Kästen): 06.11.2015 Kapitel 5 153 Veranschaulichung 06.11.2015 Kapitel 5 154 Nächstes Kapitel Priority Queues (Damit ist Selection Sort viel besser!) 06.11.2015 Kapitel 5 155 Nachtrag zu While Schleifen (1) • Wie kann man die Laufzeit von for-Schleifen analysieren? • Einfach: for-Schleifen haben Zähler - for (i=0, i<X, i++) {} wird X mal ausgeführt • while-Schleifen haben keinen Zähler - Idee: Führe künstlich einen „Zähler“ ein, resp. eine Grösse die in jeder (oder jeder zweiten etc.) Iteration strikt zu oder abnimmt - Nennen wir Potenzialfunktion! - Hat nichts mit amortisierter Analyse mit Potenzialfunktionen zu tun! 06.11.2015 Kapitel 5 156 Nachtrag zu While Schleifen (2) • Beispiel: i := N; while (i>1) i:=i/2; • Mögliche Potenzialfunktion: = i; • Es gilt – – – – – – – 0 = N und j+1 = j / 2 Sobald j · 1 terminiert‘s Wieviel Iterationen hat die While-Schleife? Was wäre, wenn man in jedem Schritt i:=i-1 rechnen würde? Was wäre, wenn man in jedem Schritt i:=sqrt(i) rechnen würde? Was wäre, wenn man in jedem Schritt i:=log(i) rechnen würde? Was wäre, wenn in der Schleife noch mehr Code wäre? 06.11.2015 Kapitel 5 157