Übung Praktische Informatik I HWS 2008/2009 Benjamin Guthier Lehrstuhl für Praktische Informatik IV Universität Mannheim [email protected] Praktische Informatik I Benjamin Guthier 28.11.08 11 - 1 Heutige große Übung • Evaluation der großen Übung • B-Bäume vom vorigen Mal • Komplexität von Algorithmen • Testverfahren Praktische Informatik I Benjamin Guthier 28.11.08 11 - 2 B-Bäume • Ein B-Baum ist Baum mit folgenden Eigenschaften • • • • • • Rang m > 2 Jeder Knoten hat höchstens m und mindestens m/2 Nachfolger Wurzel hat mindestens zwei Nachfolger Jeder Knoten hat genau einen Schlüssel weniger als Nachfolger Alle Blattknoten haben die gleiche Tiefe Blattknoten haben keine Nachfolger • Tafelbeispiel... • Aus den Eigenschaften folgt • B-Baum garantiert eine gewisse Balanciertheit • Wächst und schrumpft in Richtung der Wurzel • B-Baum hat geringere Tiefe als Binärbaum mit gleicher Schlüsselanzahl Praktische Informatik I Benjamin Guthier 28.11.08 11 - 3 B-Bäume (cont.) • Große Werte für Rang m sind üblich • Beispiel m=200: Knoten haben 200 Nachfolger und 199 Schlüssel • Spezialfall m=4: 2-3-4-Baum • Jeder Knoten hat höchstens vier und mindestens zwei Nachfolger • Obiges gilt auch für die Wurzel • Knoten haben entweder einen, zwei oder drei Schlüssel • Variante B+-Bäume werden im NTFS-Dateisystem eingesetzt Praktische Informatik I Benjamin Guthier 28.11.08 11 - 4 Einfügen in B-Baum • Einfügen ähnlich wie in Binärbaum • Einfügen beginnt im Wurzelknoten • Einfügestelle (Blattknoten) wird gesucht • Füge Wert in sortierte Schlüssel-Liste des Blattknotens ein • Es kann passieren, dass Schlüssel-Liste nun mehr als m-1 Schlüssel enthält. Dann: • Teile betroffenen Blattknoten in zwei Hälften (Split) • Jede Hälfte speichert halbe Schlüssel-Liste • Ziehe ehemals mittleren Schlüssel in den Elternknoten • Enthält Elternknoten nun m Schlüssel, fahre rekursiv mit Split des Elternknoten fort • Split der Wurzel führt zum Einfügen eines neuen Wurzelknotens über beiden Hälften der alten Wurzel • Tafelbeispiel... Praktische Informatik I Benjamin Guthier 28.11.08 11 - 5 Komplexität von Algorithmen • Komplexität (Laufzeit) ist wichtiges Vergleichskriterium bei Algorithmen • Abschätzung der Komplexität: • • • • Welche Größe ist die Eingabelänge n? Was sind die Grundoperationen des Algorithmus? Was ist deren Komplexität? Wie oft werden die Grundoperationen in Abhängigkeit von n ausgeführt? • Komplexität = Komplexität der Grundoperationen und Häufigkeit deren Ausführung • Ist Funktion von n • Vereinfachen zu Ausdruck in O-Notation mittels Rechenregeln Praktische Informatik I Benjamin Guthier 28.11.08 11 - 6 Komplexität von Algorithmen (2) • Beispiele für die Eingabelänge n in Algorithmen • • • • Länge einer Liste oder eines Arrays in Sortieralgorithmen Anzahl der Bits einer Zahl im Primzahltest Seitenlänge einer quadratischen Matrix bei Matrixmultiplikation Seitenlänge eines Bildes bei Bildverarbeitungsoperationen • Bestimme Grundoperationen mit leicht abschätzbarer Komplexität (konstant O(1), linear O(n)) • Vergleich zweier Zahlen fester Länge: • Addition zweier Zahlen fester Länge: • Adressieren eines Array-Elements: • Adressieren eines Listen-Elements: Praktische Informatik I Benjamin Guthier konstant konstant konstant proportional zu Listenlänge 28.11.08 11 - 7 Komplexität von Algorithmen (3) • Häufigkeit der Ausführung der Grundoperationen hängt meist von n ab • Für feste n ausprobieren: Für n=4: 8x ausgeführt n=5: 10x ausgeführt n=8: 16x ausgeführt • Verallgemeinerung zu Formel: Operation wird 2*n mal ausgeführt • Hierin liegt meist die größte Herausforderung! • Gesamtkomplexität ergibt sich aus • Komplexität der Grundoperationen • Anzahl deren Ausführungen • Vereinfachung des Terms durch O-Notation und Rechenregeln Praktische Informatik I Benjamin Guthier 28.11.08 11 - 8 Beispiel: Suche in balanciertem Binärbaum • Eingabelänge n: Anzahl der Knoten im Binärbaum • Grundoperationen • Vergleich zweier Schlüssel: konstant • Abstieg in Nachfolgeknoten: konstant • Wie oft ausgeführt? • • • • Anzahl der Vergleiche ist gleich der Höhe des Ergebnisknotens Höhe wird nach oben durch Höhe h des Baums abgeschätzt Baum mit Höhe h speichert ca. 2h Schlüssel Höhe in Abhängigkeit von n: n = 2h => ld(n) = h • Komplexität: Konstante * Baumhöhe • c * h = c * ld(n) => O(c * ld(n)) = O(ld n) Praktische Informatik I Benjamin Guthier 28.11.08 11 - 9 Beispiel: „Teile und Herrsche“-Sortierung TH-Sortieren(Liste) { if (Listenlänge > 1) { TH-Sortieren(linke Listenhälfte); TH-Sortieren(rechte Listenhälfte); zusammenfügen(sortierte Hälften); } } • Grundidee: • Liste rekursiv halbieren bis Listen der Länge 1 entstehen • Zwei sortierte Hälften in einem Durchgang zu langer sortierter Liste zusammenfügen Praktische Informatik I Benjamin Guthier 28.11.08 11 - 10 Beispiel: „Teile und Herrsche“-Sortierung (2) Halbieren Sortiert zusammenfügen Liste der Länge n=8 Praktische Informatik I Benjamin Guthier 28.11.08 11 - 11 Komplexität der TH-Sortierung • Eingabelänge n ist Länge der zu sortierenden Liste • Grundoperationen und deren Komplexität • Zerteilen einer Liste in zwei Hälften konstant bei geschickter Implementierung • Sortiertes Zusammenfügen zweier Listen Kosten proportional zur Länge der Ergebnisliste (linear) • Zerteilen der Liste wird n-1 mal ausgeführt • Klar, weil: Teilung in n Stücke erfordert n-1 Schnitte • Laufzeit: (n-1)*c = nc - c • Als Funktion von n liegt (nc - c) in O(n) Praktische Informatik I Benjamin Guthier 28.11.08 11 - 12 Komplexität der TH-Sortierung (2) • Aufwand des Zusammenfügens 1 mal zu Liste der Länge n 2 mal zu Liste der Länge n/2 4 mal zu Liste der Länge n/4 • Aufwand: 1*n + 2*n/2 + 4*n/4 + ... = n + n + n + ... = k*n • Bei Verdopplung von n wächst k um eins, also k = ld(n) • Gesamtkomplexität: Teilen + Zusammenfügen • O(n) + O(n * ld(n)) = O(n * ld(n)) Praktische Informatik I Benjamin Guthier 28.11.08 11 - 13 Testen • Aufgabenstellung: Erhöhen der Wahrscheinlichkeit der Korrektheit einer Implementierung durch wiederholtes Ausführen • Ausgangspunkt des Tests • Genaue Spezifikation des Algorithmus • Implementierung des Algorithmus • Gesucht ist Menge von Eingaben, die alle Problemfälle beinhaltet • Testverfahren geben Hinweise zur Wahl der Menge der Eingaben • Unterscheiden sich hauptsächlich in der Abdeckung Praktische Informatik I Benjamin Guthier 28.11.08 11 - 14 Beispiel zum Testen • Methode: String removeSpaces(String) • Spezifikation • Eingabe ist beliebiger String • Methode entfernt alle Leerzeichen aus Zeichenkette • Gibt String ohne Leerzeichen zurück. Worte wurden zusammengeschoben • Welche Eingaben sind interessante Testfälle? • Ermitteln von Testfällen ist kreativer Prozess • Testverfahren unterstützen diesen Prozess systematisch Praktische Informatik I Benjamin Guthier 28.11.08 11 - 15 Vollständiger Test • Jede mögliche Eingabe wird getestet und Ausgabe überprüft • Testmenge ist Menge aller möglichen Zeichenketten • Zur Vereinfachung: Alle Zeichenketten mit zehn oder weniger Zeichen • Ein Zeichen kann 2 16 • Es gibt (2 = 65536 verschiedene Zustände annehmen 16 10 ) = 2160 mögliche Eingabestrings Praktische Informatik I Benjamin Guthier 28.11.08 11 - 16 Vollständiger Test • Jede mögliche Eingabe wird getestet und Ausgabe überprüft • Testmenge ist Menge aller möglichen Zeichenketten • Zur Vereinfachung: Alle Zeichenketten mit zehn oder weniger Zeichen • Ein Zeichen kann 2 16 • Es gibt (2 = 65536 verschiedene Zustände annehmen 16 10 ) = 2160 mögliche Eingabestrings • Also ca. 1500000000000000000000000000000000000000000000000 Testfälle Praktische Informatik I Benjamin Guthier 28.11.08 11 - 17 Andere Testverfahren • Anweisungstest: Wähle Testdaten so, dass jede Anweisung mindestens einmal ausgeführt wird. • Verzweigungstest: Jede Verzweigung muss mindestens einmal ausgeführt werden. • In Praxis: Jede Bedingung bei if/while/for muss einmal true und einmal false ergeben • Bedeutet für Schleifen: Schleife muss 0-mal und 1-mal durchlaufen werden • Wegetest: Fordere zusätzlich, dass jede Schleife k-mal durchlaufen wird, für festes k > 1 Praktische Informatik I Benjamin Guthier 28.11.08 11 - 18 Code-Inspection • Ist kein Testverfahren. Code wird nicht ausgeführt. • Finden von typischen und häufig gemachten Fehlern durch genaues Hinschauen • Code-Inspection lernt man hauptsächlich durch Programmiererfahrung Praktische Informatik I Benjamin Guthier 28.11.08 11 - 19