Notizen Algorithmen und Datenstrukturen (für ET/IT) Sommersemester 2014 Dr. Tobias Lasser Computer Aided Medical Procedures Technische Universität München Probeklausur Notizen • Wann? während Zentralübung am Mittwoch, 21. Mai 2014 • Wo? Hörsaal 1200 • Wie? • 9:45 - 10:30: Bearbeitungszeit Probeklausur • 10:30 - 11:15: Besprechung der Probeklausur • Erlaubtes Material: • nur 1 DIN A4 Blatt, handbeschrieben • keine Bücher, Skripten, Ausdrucke, Smartphones, etc. • Wozu? • Simulation der tatsächlichen Prüfungssituation am 16. Juli 2014 • Vertrautmachen mit der Art von Prüfungsaufgaben 3 Programm heute Notizen 1 Einführung 2 Grundlagen von Algorithmen 3 Grundlagen von Datenstrukturen 4 Grundlagen der Korrektheit von Algorithmen 5 Grundlagen der Effizienz von Algorithmen 6 Grundlagen des Algorithmen-Entwurfs → Wiederholung und Anwendungsbeispiele 4 Kapitel 1: Einführung Definition Algorithmus Notizen • Algorithmus Definition: M. Broy: Informatik: Eine grundlegende Einführung Ein Algorithmus ist ein Verfahren ” • mit einer präzisen (d.h. in einer genau festgelegten Sprache abgefassten), • endlichen Beschreibung, • unter Verwendung Definition• Datenstruktur e↵ektiver (d.h. tatsächlich ausführbarer), • elementarer (Verarbeitungs-) Schritte.“ • Datenstruktur Definition: Definition Datenstruktur (nach Prof. Eckert) Eine Datenstruktur ist eine • logische Anordnung von Datenobjekten, 26 • die Informationen repräsentieren, • den Zugri↵ auf die repräsentierte Information über Operationen auf Daten ermöglichen und • die Information verwalten. 5 Kapitel 1: Einführung Notizen Wie funktioniert ein Computer? Algorithmus Datenstrukturen Hochsprache (z.B. C, C++) Betriebssystem Assembler Maschinensprache Computertechnik Mikroarchitektur Digitale Logik Digitaltechnik Transistoren, Verdrahtung Schaltungstechnik Masken-Layout, Halbleiter Hardware Algorithmen und Software • Einordnung in Computer-Schema: Schema nach Prof. Diepold: Grundlagen der Informatik. 4 6 Kapitel 2: Grundlagen von Algorithmen Notizen 2.1 Darstellung von Algorithmen 2.2 Elementare Bausteine 2.3 Logische Ausdrücke 7 Struktogramm • Output: Zahl x = max(a, b) • •formale Sprache zur Beschreibung von Algorithmen Diagramm zur Strukturdarstellung, nicht ausführbar Problem: präzise Beschreibung der Schritte Lösung: Pseudocode • •fest definierte Syntax eingeführt von Nassi/Shneiderman 1973, normiert als DIN Kapitel 2.1: Darstellung von Algorithmen 66261 • ein Compiler/Interpreter wandelt Programm in ausführbare Algorithmus : max (a , b ) Input : a , b x=a Falls b > a dann x=b Ende Falls Output : x x=a • Beispiele: Assembler,b>a? C++, Java ja x=b • Algorithmus in x x=a ja nein C++: int max ( int a , int b ) { 7 int x = a ; if ( b > a ) x = b; return x ; } Input: a,b b>a? Notizen Form fürmax(a,b) Rechner um x=b 10 nein Output: x 11 • Churchsche These: alle “vernünftigen” Beschreibungen sind äquivalent 8 Kapitel 2.2: Elementare Bausteine Notizen Bausteine von Algorithmen • Bausteine von Algorithmen: Elementare Bausteine Alle berechenbaren Algorithmen lassen sich mit vier elementaren Bausteinen darstellen: 1 Elementarer Verarbeitungsschritt (z.B. Zuweisung an Variable) 2 Sequenz (elementare Schritte nacheinander) 3 Bedingter Verarbeitungsschritt (z.B. if/else) 4 Wiederholung (z.B. while-Schleife) 22 9 Kapitel 2.3: Logische Logische Werte undAusdrücke Verknüpfungen Grundrechenarten“ mit logischen Werten: ” Notizen Wahrheitstabelle: • Konjunktion: ^ : B ⇥ B ! B • ähnlich zu Multiplikation bei Zahlen • auch bezeichnet als UND bzw. AND a 0 0 1 1 b 0 1 0 1 a^b 0 0 0 1 • Disjunktion: _ : B ⇥ B ! B • ähnlich zu Addition bei Zahlen • auch bezeichnet als ODER bzw. OR a 0 0 1 1 b 0 1 0 1 a_b 0 1 1 1 a 0 1 ¬a 1 0 • Negation: ¬ : B ! B • auch bezeichnet als NICHT bzw. NOT 21 • Verknüpfungen NAND, NOR, XOR • Verknüpfungen Implikation, Äquivalenz • Rechenregeln: NOT vor AND vor OR, De Morgan Gesetze 10 Kapitel 3: Elementare Datenstrukturen Notizen 3.1 Primitive Datentypen und Zahldarstellung 3.2 Felder als sequentielle Liste 3.3 Zeichen und Zeichenfolgen 3.4 Felder als verkettete Liste 3.5 Abstrakte Datentypen 3.6 Stacks 3.7 Queues 11 Kapitel 3.1: Primitive Datentypen und Zahldarstellung • Bits und Bytes Notizen Bit 0 Bit 7 1 Byte = 8 Bit • Primitive Datentypen: char, short, long, signed oder unsigned • Zahldarstellung mit Polynom p(x), wobei x Basis • x = 10: Dezimaldarstellung • x = 2: Binärdarstellung • Wie viele Ziffern m pro Zahl z? m = blogx (z)c + 1 • Größte Zahl pro m Ziffern? zmax = x m − 1 • 2-Komplement Darstellung • Floating Point Zahlen: f = (−1)V · (1 + M) · 2E −bias • float, double 12 Kapitel 3.2: Felder als sequentielle Liste Notizen • Feld als sequentielle Liste / Array: A[n-1] A[n-2] .. .. A[1] A[0] • Operationen: elementAt: O(1), insert: O(n), erase: O(n) • insert und erase erfordern Umkopieren der Elemente: 25 16 9 4 1 25 16 9 8 4 1 25 16 9 4 1 0 25 16 9 4 1 13 Kapitel 3.3: Zeichen und Zeichenfolgen Notizen • Zeichen codiert als ASCII, Unicode, etc. • Folge von Zeichen: String • als String-Literal: “AuD” • als Feld von Zeichen: 'D' 'u' 'A' 14 Kapitel 3.4: Felder als verkettete Liste • Feld als verkettete Liste: start Notizen Daten Daten Daten Daten next next next next null • Operationen: elementAt: O(n), insert: O(n), erase: O(n) • Feld als doppelte verkettete Liste: null start prev prev prev prev Daten Daten Daten Daten next next next next stop null • Operationen: elementAt: O(n), insert: O(n), erase: O(n) 15 Kapitel 3.5: Abstrakte Datentypen Notizen Definition Abstrakter Datentyp • Definition abstrakter Datentyp: Abstrakter Datentyp (englisch: abstract data type, ADT) Ein abstrakter Datentyp ist ein mathematisches Modell für bestimmte Datenstrukturen mit vergleichbarem Verhalten. Ein abstrakter Datentyp wird indirekt definiert über • mögliche Operationen auf ihm sowie • mathematische Bedingungen (oder: constraints) über die Auswirkungen der Operationen (u.U. auch die Kosten der Operationen). • Abstrakte Variable V mit • Operationen (load, store) 23 • Bedingungen (load(V) liefert Wert x von letztem store(V, x)) 16 Kapitel 3.6: Stacks Notizen • Stack als abstrakter Datentyp mit • Operationen (push, pop, top, isEmpty, initialize) • Bedingungen (z.B. push(S, x); store(V, pop(S)) äquivalent zu store(V, x)) "pop" Piz za Piz za Piz za #3 #2 #1 neu e Piz za • Stack implementiert als • sequentielle Liste • verkettete Liste • beide mit Komplexität von push, pop, top: O(1) 17 Kapitel 3.7: Queues Notizen • Queue als abstrakter Datentyp mit • Operationen (dequeue, enqueue, isEmpty, initialize) • Bedingungen (z.B. enqueue(Q, x); store(V, dequeue(Q)) äquivalent zu store(V, x)) Person verlässt Schlange Person stellt sich an • Queue implementiert als • verkettete Liste • sequentielle Liste (z.B. zirkulär) • beide mit Komplexität von dequeue, enqueue: O(1) • als Kuriosität: als zwei Stacks (dequeue hat hier worst-case Komplexität O(n)) 18 Kapitel 4: Grundlagen der Korrektheit von Algorithmen Notizen 4.1 Motivation und Spezifikation 4.2 Verifikation 4.3 Beispiel: Insertion Sort 4.4 Validation 19 Kapitel 4.1: Motivation und Spezifikation Notizen • Software-Fehler sind leider alltäglich • Korrektheit ist relativ bezüglich der Spezifikation 20 Kapitel 4.2: Verifikation Notizen • Verifikation: formaler Beweis der Korrektheit bzgl. Spezifikation • mit Vor- und Nachbedingungen {VOR} ANW {NACH} für die vier elementaren Bausteine: • • • • für für für für elementaren Verarbeitungsschritt Sequenz bedingten Verarbeitungsschritt Wiederholung mit Schleifeninvariante • Verifikation ist aufwendig und teilweise automatisierbar 21 Kapitel 4.3: Beispiel Insertion Sort Notizen • Insertion Sort: Sortieren durch direktes Einfügen • Komplexität: • best case: O(n) • worst case: O(n2 ) • formale Verifikation von Insertion Sort Pseudocode mit Schleifeninvariante 22 Kapitel 4.4: Validation Notizen • Validation: informeller Nachweis der Korrektheit durch systematisches Testen • leider oft: Validation statt Verifikation • Validation auch hilfreich falls Verifikation erfolgt • Validation durch systematisches Testen: • Blackbox-Test • Whitebox-Test • Regressions-Test • Integrations-Test • Testen in der Praxis z.B. mit assert und Unit Test Frameworks • fehlertolerantes und fehlerpräventives Programmieren 23 Kapitel 5: Grundlagen der Effizienz von Algorithmen Notizen 5.1 Motivation 5.2 RAM-Modell 5.3 Landau-Symbole 24 Kapitel 5.1: Motivation Notizen • Komplexitätsanalyse von Algorithmen: Bedarf an Speicherplatz und Rechenzeit • Komplexität abhängig von Eingabegröße n → Wachstumsverhalten 48 2n n² n*ln(n) 40 n 32 24 16 8 ln(n) 0 8 16 24 32 40 48 56 64 72 • ausführliche Komplexitätsanalyse von Insertion Sort mit Konstanten (aufwendig) 25 Kapitel 5.2: RAM-Modell Notizen • RAM-Modell: einfaches Rechnermodell zur Laufzeitanalyse • nur sequentielle Ausführung • keine Speicherlatenz • alle elementaren Verarbeitungsschritte benötigen eine Wachstumsraten illustriert Zeiteinheit Annahme: Rechner mit 1GHz Taktfrequenz • eine Operation benötigt 1ns (nano-Sekunde) • der höchste •Term n bezeichne Anzahl Operationen dominiert Laufzeit: n T (n) = ln(n) T (n) = n T (n) = n ln(n) T (n) = n2 T (n) = 2n 10 20 30 40 50 100 1000 10000 100000 1 · 106 1 · 107 1 · 108 1 · 109 0.003µs 0.004µs 0.005µs 0.005µs 0.006µs 0.007µs 0.010µs 0.013µs 0.017µs 0.020µs 0.023µs 0.027µs 0.030µs 0.01µs 0.02µs 0.03µs 0.04µs 0.05µs 0.1µs 1.0µs 10µs 0.1ms 1ms 0.01s 0.1s 1s 0.033µs 0.086µs 0.147µs 0.213µs 0.282µs 0.644µs 9.966µs 130µs 1.67ms 19.93ms 0.23s 2.66s 29.9s 0.1µs 0.4µs 0.9µs 1.6µs 2.5µs 10µs 1ms 100ms 10s 16.7min 1.16 days 115.7 days 31.7 years T (n) = n! 1µs 3.63ms 1ms 77.1 years 1s 8.4 · 1015 years 18.3min 13 days 4 · 1013 years Tabelle adaptiert von “The Algorithm Design Manual”, S. Skiena, Springer 8 26 Kapitel 5.3: Landau-Symbole Notizen Landau-Symbol ⇥ • Landau-Symbol Θ: Landau-Symbol ⇥ Sei g : R ! R eine Funktion. Das Landau-Symbol ⇥(g ) ist definiert als die Menge ⇥(g ) := f : R ! R : es existieren c1 , c2 > 0, n0 2 N so dass für alle n n0 gilt: 0 c1 g (n) f (n) c2 g (n) Für f : R ! R mit f 2 ⇥(g ) schreiben wir kurz: f = ⇥(g ). Landau-Symbol O • f ist also • Landau-Symbol O: bis auf konstanten Faktor im wesentlichen “gleich” der Funktion g für n Landau-Symbol O • n0 man sagt auch: g ist asymptotisch scharfe Schranke von f Sei g(von :R! R eine oben und Funktion. unten) Das Landau-Symbol O(g ) ist definiert als die Menge • Kurznotation: f = ⇥(g ) oder f (n) = ⇥(g (n)) O(g ) := {f : R ! R : es existieren c > 0 und n0 2 N so dass für alle n n0 gilt: 0 f (n) cg (n)} 17 Für f : R ! R mit f 2 O(g ) schreiben wir kurz: f = O(g ). • man sagt auch: g ist asymptotisch obere Schranke von f • auch genannt: “gross-O-Notation” • aus f = ⇥(g ) folgt automatisch f = O(g ) 27 Kapitel 5.3: Landau-Symbole Notizen • Kategorisierung der Laufzeit von Algorithmen • O(1): konstant • O(log n): logarithmisch • O(n): linear • O(n log n): loglinear • O(n2 ): quadratisch • O(2n ): exponentiell • Rechenregeln für die vier elementaren Bausteine • elementarer Verarbeitungsschritt: O(1) • Sequenz: Addition in O-Notation • bedingter Verarbeitungsschritt: Maximum von if/else sowie O(1) für Bedingung • Wiederholung: Anzahl Schleifendurchläufe multipliziert mit Komplexität Schleifenkörper sowie jeweils O(1) für Bedingung 28 Kapitel 6: Grundlagen des Algorithmen-Entwurfs Notizen 6.1 Entwurfsprinzipien 6.2 Divide and Conquer 6.3 Greedy-Algorithmen 6.4 Backtracking 6.5 Dynamisches Programmieren 29 Kapitel 6.1: Entwurfsprinzipien Notizen • kein Patentrezept zum Entwurf von Algorithmen • Prinzip: Verfeinerung bzw. Top-Down Entwurf • Vorgehen mit schrittweiser Verfeinerung des Lösungsansatzes • Prinzip: Algorithmen-Muster bzw. Design Patterns • Lösungsverfahren f’ur bestimmte Problemklasse • Anpassung an konkrete Problemstellung 30 Kapitel 6.2: Divide and Conquer Notizen Muster: Divide and Conquer Divide and Conquer-Muster als Pseudocode: • Algorithmen-Muster: Divide and Conquer Input: Aufgabe A DivideAndConquer(A): if (A klein) { löse A explizit; } else { teile A in Teilaufgaben A1 , . . . , An auf; DivideAndConquer(A1 ); ... DivideAndConquer(An ); setze Lösung für A zusammen aus Lösungen für A1 , . . . , An } • Beispiel: MergeSort • Komplexität O(n log n) mit Rekursionsbaum • benötigt extra Speicher • Beispiel: QuickSort • Komplexität im Mittel O(n log n) • worst case: O(n2 ) 17 31 Algorithmen-Muster: Greedy Kapitel 6.3: Greedy-Algorithmen Notizen Greedy-Muster als Pseudocode: • Algorithmen-Muster: Greedy Input: Aufgabe A Greedy(A): while (A nicht gelöst) { wähle bestmöglichen Schritt; // Greedy Strategie baue Schritt in Lösung ein; } • Beispiel: Wechselgeld, minimale Anzahl Münzen • Beispiel: Glasfasernetz, minimale Spannbaum 6 K2 K1 K4 7 1 9 10 K3 4 5 K1 2 1 10 K5 3 2 8 K2 3 K3 K5 6 K4 32 Algorithmen-Muster: Backtracking Voraussetzungen: • Lösungs(teil)raum repräsentiert als Konfiguration K • K ist Start-Konfiguration Kapitel 6.4: Backtracking 0 Notizen • jede Konfiguration Ki kann direkt erweitert werden • Algorithmen-Muster: Backtracking • für jede Konfiguration ist entscheidbar, ob Lösung Input: Konfiguration K Backtrack(K ): if (K ist Lösung) { gib K aus; } else { for each (direkte Erweiterung K 0 von K ) { Backtrack(K 0 ); } } • Beispiel: Labyrinth, Maus mit Käse 26 (1,1) 1 (1,2) 2 (2,2) (2,1) 3 (3,1) 1 2 (1,3) (3,2) (2,3) (3,3) 3 • Beispiel: Traveling Salesman Problem • Beispiel: Acht-Damen-Problem 33 Kapitel 6.5: Dynamisches Programmieren Notizen • Prinzip dynamisches Programmieren • statt Rekursion aufwärts von kleinstem Teilproblem rechnen • Zwischenergebnisse Fibonacci Zahlen in Tabellen speichern • Beispiel: Fibonacci Folge Fibonacci Folge Die Fibonacci Folge ist eine Folge natürlicher Zahlen f1 , f2 , f3 , . . ., für die gilt fn = fn 1 + fn 2 für n 3 mit Anfangswerten f1 = 1, f2 = 1. • eingesetzt von Leonardo Fibonacci zur Beschreibung von Wachstum einer Kaninchenpopulation • Folge lautet: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, . . . • berechenbar z.B. via Rekursion 38 34 Warnung! Notizen ACHTUNG! • Vorlesung heute dient nur der Wiederholung und Einordnung des bereits behandelten Stoffes • Anwendungs-Szenarien (und Hintergründe, Details dazu) sind NICHT klausur-relevant! 35 Anwendungs-Szenarien Notizen separate Präsentation 36 Warnung! Notizen ACHTUNG! • Vorlesung heute dient nur der Wiederholung und Einordnung des bereits behandelten Stoffes • Anwendungs-Szenarien (und Hintergründe, Details dazu) sind NICHT klausur-relevant! 37 Zusammenfassung Notizen 1 Einführung 2 Grundlagen von Algorithmen 3 Grundlagen von Datenstrukturen 4 Grundlagen der Korrektheit von Algorithmen 5 Grundlagen der Effizienz von Algorithmen 6 Grundlagen des Algorithmen-Entwurfs → Wiederholung und Anwendungsbeispiele 38 Notizen