Algorithmen und Datenstrukturen

Ähnliche Dokumente
Algorithmen und Datenstrukturen

Übung zu Algorithmen und Datenstrukturen (für ET/IT)

Übung zu Algorithmen und Datenstrukturen (für ET/IT)

Übung zu Algorithmen und Datenstrukturen (für ET/IT)

Technische Universität München SoSe 2015 Institut für Informatik I Mai 2015 Dr. Tobias Lasser. Aufgabe 1 Rechnen mit Landau-Symbolen

Algorithmen und Datenstrukturen (für ET/IT)

Grundlagen: Algorithmen und Datenstrukturen

Technische Universität München SoSe 2018 Fakultät für Informatik, I Mai 2018 Dr. Stefanie Demirci

Informatik II, SS 2018

Programmieren und Problemlösen

Datenstrukturen und Algorithmen (SS 2013)

Übung Algorithmen und Datenstrukturen

Übung: Algorithmen und Datenstrukturen SS 2007

Informatik II, SS 2016

Rekursionen (Teschl/Teschl 8.1/8.2)

Algorithmen und Datenstrukturen 1 VL Übungstest WS November 2008

Abgabe: (vor der Vorlesung) Aufgabe 2.1 (P) O-Notation Beweisen Sie die folgenden Aussagen für positive Funktionen f und g:

Ordnen Sie die folgenden Funktionen nach ihrer asymptotischer Komplexität in aufsteigender Reihenfolge: i=1 4i + n = 4 n. i=1 i + 3n = 4 ( n(n+1)

Suchen und Sortieren

Tutoraufgabe 1 (Sortieralgorithmus):

Übung Algorithmen und Datenstrukturen

Das Suchproblem. Gegeben Menge von Datensätzen. Beispiele Telefonverzeichnis, Wörterbuch, Symboltabelle

Abschnitt 19: Sortierverfahren

Informatik II, SS 2018

Datenstrukturen und Algorithmen (SS 2013) Prof. Dr. Leif Kobbelt Thomas Ströder, Fabian Emmes, Sven Middelberg, Michael Kremer

INSERTION-SORT: Ja, Es wird immer das erste, kleinste Element an die neue Liste angehängt.

UE Algorithmen und Datenstrukturen 1 UE Praktische Informatik 1. Übung 9. Sortieren

Grundlagen: Algorithmen und Datenstrukturen

Übung Algorithmen und Datenstrukturen

WS 2009/10. Diskrete Strukturen

2. Grundlagen. Beschreibung von Algorithmen durch Pseudocode. Korrektheit von Algorithmen durch Invarianten.

Kostenmodell. Daniel Graf, Tobias Pröger. 22. September 2016 (aktualisierte Fassung 5 vom 9. Oktober 2016)

Übung zur Vorlesung Berechenbarkeit und Komplexität

Übung Algorithmen und Datenstrukturen

Informatik I Komplexität von Algorithmen

f 1 (n) = log(n) + n 2 n 5 f 2 (n) = n 3 + n 2 f 3 (n) = log(n 2 ) f 4 (n) = n n f 5 (n) = (log(n)) 2

Christoph Niederseer, Michaela Mayr, Alexander Aichinger, Fabian Küppers. Wissenschaftl. Arbeitstechniken und Präsentation

Das Suchproblem 4. Suchen Das Auswahlproblem Suche in Array

Das Suchproblem. Gegeben Menge von Datensätzen. Beispiele Telefonverzeichnis, Wörterbuch, Symboltabelle

Das Suchproblem 4. Suchen Das Auswahlproblem Suche in Array

Algorithmen und Datenstrukturen 1 Kapitel 5

2. Effizienz von Algorithmen

Algorithmen und Datenstrukturen Effizienz und Funktionenklassen

Übersicht. Datenstrukturen und Algorithmen. Übersicht. Heaps. Vorlesung 8: Heapsort (K6) Joost-Pieter Katoen. 7. Mai 2015

Komplexität von Algorithmen:

Algorithmen und Datenstrukturen I. Grundlagen. Prof. Dr. Oliver Braun. Fakultät für Informatik und Mathematik Hochschule München

Algorithmen und Datenstrukturen (für ET/IT)

Algorithmen und Datenstrukturen 1

Algorithmen und Datenstrukturen (ESE) Entwurf, Analyse und Umsetzung von Algorithmen (IEMS) WS 2012 / 2013 Vorlesung 3, Donnerstag 7.

(08 - Einfache Sortierverfahren)

A6.1 Logarithmus. Algorithmen und Datenstrukturen. Algorithmen und Datenstrukturen. A6.1 Logarithmus. A6.2 Landau-Notation. A6.

7. Sortieren Lernziele. 7. Sortieren

Algorithmen und Datenstrukturen I Grundlagen

Ordnen Sie die folgenden Funktionen nach ihrer asymptotischer Komplexität in aufsteigender Reihenfolge: i=1 4i + n = 4 n. i=1 i + 3n = 4 ( n(n+1)

Algorithmen und Datenstrukturen (ESE) Entwurf, Analyse und Umsetzung von Algorithmen (IEMS) WS 2014 / 2015 Vorlesung 3, Donnerstag 6.

2 Wachstumsverhalten von Funktionen

Kapitel 10. Komplexität von Algorithmen und Sortieralgorithmen

Algorithmen und Datenstrukturen (für ET/IT)

Technische Universität Wien Institut für Computergraphik und Algorithmen Arbeitsbereich für Algorithmen und Datenstrukturen

Heapsort / 1 A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]

Praktische Informatik I - Algorithmen und Datenstrukturen Wintersemester 2006/ Algorithmen und ihre formalen Eigenschaften, Datenstrukturen

9. Rekursion. 1 falls n 1 n (n 1)!, andernfalls. Experiment: Die Türme von Hanoi. Links Mitte Rechts. Mathematische Rekursion

Präsenzübung Datenstrukturen und Algorithmen SS 2014

Übungsblatt 1. f(n) = f(n) = O(g(n)) g(n) = O(f(n)) Zeigen oder widerlegen Sie: 3 n = Θ(2 n ) Aufgabe 1.2 Gegeben sei die folgende Funktion:

AlgoDat Fragen zu Vorlesung und Klausur

ADS: Algorithmen und Datenstrukturen 1

3.2. Korrektheit und Komplexität am Beispiel: Sortieren Sortieren ist eine wichtige Basis-Operation für komplexe Algorithmen

Algorithmen und Datenstrukturen

Asymptotik und Laufzeitanalyse

Datenstrukturen und Algorithmen Beispiellösung zu Heimübungsblatt 7. Abbildung 1: Das Array A als Baum (vgl. Foliensatz 16, Folie 3)

Stabiles Sortieren. Dieses Prinzip lässt sich natürlich auf beliebiege andere Zahlensystem oder auch komplett anders gestaltete Mengen übertragen.

Algorithmen und Datenstrukturen (für ET/IT)

6 Quicksort. die mittlere Laufzeit Θ(n log n) beträgt und. die in der asymptotischen Notation verborgenen Konstanten sehr klein sind.

Rekursionsbäume Aufstellen eines Baumes dessen Knoten die Laufzeit auf jeder Rekursionsstufe darstellen und Aufsummieren

Klausur Algorithmen und Datenstrukturen

Grundlagen: Algorithmen und Datenstrukturen

3.2. Divide-and-Conquer-Methoden

A7.1 Untere Schranke. Algorithmen und Datenstrukturen. A7.1 Untere Schranke. Algorithmen und Datenstrukturen. A7.2 Quicksort. A7.

3 Numerisches Rechnen

Sortieren II / HeapSort Heaps

Algorithmen und Datenstrukturen 1-1. Seminar -

Übungsklausur Algorithmen I

Informatik II, SS 2016

Übungen zu Algorithmentechnik WS 09/10

Algorithmen und Datenstrukturen 1-3. Seminar -

Bucketsort. Korrektheit. Beispiel. Eingabe: Array A mit n Elementen im Bereich [0,1) Annahme: die Elemente sind in [0,1) gleichverteilt.

Eingabe: Array A mit n Elementen im Bereich [0,1) Annahme: die Elemente sind in [0,1) gleichverteilt

Einführung in die Programmierung I. 6. Sortieren. Stefan Zimmer

Abschnitt 7: Komplexität von imperativen Programmen

Algorithmen und Datenstrukturen (für ET/IT)

Datenstrukturen & Algorithmen

Algorithms & Data Structures 2

Übung Datenstrukturen. Sortieren

1. Musterlösung. Problem 1: Average-case-Laufzeit vs. Worst-case-Laufzeit ** i=1

Algorithmen und Datenstrukturen

Kap. 3ff: Untere Laufzeitschranke und Lineare Verfahren

Motivation Überblick

Algorithmen und Datenstrukturen 1

Transkript:

Technische Universität München WiSe 2012/13 Institut für Informatik I-16 Lösungsblatt 7 Dr. Tobias Lasser 3. Dezember 2012 Jakob Vogel Algorithmen und Datenstrukturen Aufgabe 1 Rechnen mit Landau-Symbolen (Beispiellösung) Die Definitionen der beiden für uns relevanten Landau-Symbole waren: Θ(g) := { f : R R : es existieren c 1,c 2 > 0 und n 0 N, so dass für alle n n 0 gilt: 0 c 1 g(n) f (n) c 2 g(n) O(g) := { f : R R : es existieren c > 0 und n 0 N, so dass für alle n n 0 gilt: 0 f (n) c g(n) a) Die Worst-Case-Komplexität eines Algorithmus sei Θ(n). Nachdem auch 2n = Θ(n), entspricht die Dauer eines Worst-Case-Beispiels der Länge 2n ungefähr der Dauer eines Worst- Case-Beispiels der Länge n. Die Behauptung ist falsch, da konstante Faktoren der tatsächlichen Laufzeitfunktion bei Landau-Symbolen der Einfachheit halber entfallen, und nur das grundsätzliche Wachstum abgeschätzt wird. Daher wird das doppelt so große Beispiel tatsächlich etwa doppelt so lange rechnen, wie das einfacher Größe. b) Sei die Komplexität einer Funktion f bestimmt als O(n). Dann ist die n-malige Ausführung O(n 2 ). Sei T f (n) die Laufzeitfunktion von f. Aus der Annahme folgt, dass es c und n 0 gibt, so dass 0 T f (n) c n für alle n n 0. Bei n-maliger Ausführung muss einfach multipliziert werden: 0 n T f (n) n c n = c n 2 Das ist direkt die Forderung aus der Definition von O(n 2 ), die Aussage ist korrekt! c) Falls f (n) = Θ(g(n)), dann folgt 2 f (n) = Θ(2 g(n) ). Wähle f (n) = n und g(n) = 2 n, dann gilt offensichtlich f (n) = Θ(g(n)): 0 c 1 2 n n c 2 2 n, etwa mit c 1 = c 2 = 1 2 und n 0 = 1. Nehmen wir nun an, dass die Aussage korrekt ist, und wir erhalten aus 2 f (n) = Θ(2 g(n) ) die Ungleichung 0 c 1 2 2 n 2 n c 2 2 2 n. Vereinfachen wir diese Formel nun durch Teilung durch 2 n, was wegen n > 0 ohne Umkehr der Vorzeichen problemlos möglich ist: 0 c 1 2 n 1 c 2 2 n.

2 Dies ist aber ein Widerspruch, da wir zwar ein c 2, nicht aber ein c 1 finden können, da die Folge 2 n unbeschränkt ist. Damit ist die komplette Aussage falsch, da mit der getroffenen Auswahl für f und g ein Gegenbeispiel gefunden wurde. d) n n = O(2 n ) Nehmen wir wieder an, dass die Aussage wahr ist. Dann gilt aus der Definition von O die Ungleichung 0 n n c 2 n, was sich (wieder wegen 2 n > 0 für n > 0) umformen lässt zu ( n ) n c. 2 Auch diese Folge ist unbeschränkt und wächst beliebig für große Werte von n. Damit kann keine Konstante c im Sinn einer oberen Schranke existieren. Damit ist die Aussage als falsch widerlegt! Aufgabe 2 Sortieren mittels -and-conquer-ansätzen (Beispiellösung) a) Die Idee hinter Merge Sort war ja, das Array mittig aufzuspalten, die Teile rekursiv sortieren zu lassen, und dann aus den sortierten Teilen das Ergebnis zusammenzufügen. Ausgangsdaten 2 9 4 5 8 3 1 2 2 4 5 9 8 3 1 2 2 4 5 9 8 3 1 2 2 4 5 9 8 3 1 2 2 4 5 9 3 8 1 2

3 Ergebnis 2 4 5 9 3 8 1 2 2 4 5 9 3 8 1 2 2 4 5 9 1 2 3 8 b) Beim Quick Sort ist die Strategie etwas anders. Zwar wird auch hier unterteilt, doch geschieht dies nicht mittig, sondern basierend auf einem Pivot-Element 1, bezüglich dessen in einen vorderen Teil mit kleineren Elementen und einen hinteren Teil mit größeren Elementen sortiert wird. Es gibt verschiedene Auswahlstrategien für den Pivot, und wir wählen hier immer das letzte Element. Der Quick Sort ist zwar ein -and-conquer-algorithmus, aber ein offensichtlicher Conquer-Schritt fehlt. Der Grund ist der, dass die rekursiv aufgerufene Funktion die Daten bereits richtig abliefert, und so die Zusammenfügung implizit erfolgt ist. Im folgenden Schaubild sind derartige, nur zum Verständnis aufgeführte, Schritte durch drei Punkte gekennzeichnet. Ausgangsdaten Trivial-Schritt 1 Dreh-, Angelpunkt 2 1 2 4 8 3 9 5 2 1 2 4 8 3 9 5 1 2 2 4 8 3 9 5 1 2 2 4 8 3 9 5 1 2 2 4 8 3 9 5 1 2 2 4 3 5 9 8 1 2 2 4 3 5 9 8 1 2 2 3 4 5 9 8

4 Trivial-Schritt 1 2 2 3 4 5 9 8 1 2 2 3 4 5 9 8 Trivial-Schritt......... Ergebnis Aufgabe 3 Stabilität von Sortierverfahren (Beispiellösung) Wir bezeichnen ein Sortierverfahren als stabil, wenn bei gleichrangigen Elementen während der Sortierung die vorherige Ordnung erhalten bleibt. Der Insertion Sort ist stabil. Dies ist offensichtlich, da der Algorithmus den unsortierten Teil der Reihe nach durchgeht, und das Element (von hinten her Platz schaffend) in den sortierten Teil einfügt. Sollte also ein gleichrangiges Element vorhanden sein, so wird das neue Element als dessen Nachfolger einsortiert. Der Selection Sort ist nicht stabil. Es wird zwar stets aus dem unsortierten Teil das Minimum gesucht und eingefügt, aber der Platz wird nicht durch Rücken, sonder durch Vertauschen geschaffen. Insofern kann sich hier die Reihenfolge gleichrangiger Elemente ändern. Man könnte den Selection Sort stabil machen, indem der Platz eben doch durch schrittweises Verrücken der Elemente geschaffen würde. Dies würde jedoch erheblichen Aufwand bedeuten. Der Merge Sort ist in der gegebenen Formulierung nicht stabil. Der einzige Vertauschungsfall kann dabei passieren, wenn in der Merge-Funktion im Falle gleichrangiger Anfänge der Teillisten aus dem hinteren Teil gelesen würde. Wenn wir jedoch explizit fordern, dass in diesem Falle immer nur vorne ausgelesen wird, dann ist der Merge Sort stabil. Der Quick Sort ist nicht stabil. Die Vertauschungen können laufend passieren, wenn nach der die Menge partitioniert wird. Man kann Quick Sort auch stabil implementieren, doch vernachlässigen wir diese Möglichkeit wegen ihrer Komplexität.

5 Aufgabe 4 Komplexität der Polynom-Auswertung (Beispiellösung) In dieser Aufgabe gehen wir etwas anders vor, und zählen nicht wie im RAM-Modell alle Rechenschritte, sondern begnügen uns damit, teure arithmetische Operationen zu zählen. Im vorliegenden Fall sind dies vor allem die Multiplikationen. Vergegenwärtigen Sie sich, dass wir bei einem Polynom des Grads n von n + 1 Koeffizienten ausgehen (auch wenn diese dann den Wert 0 haben können). a) Betrachten wir nochmals den Code der einfachen Implementierung: 1 p = 0; 2 for i = n down to 0 { 3 m = 1; 4 for j = 1 to i { 5 m = m x; 6 m = a[i] m; 7 p = p + m; Im Folgenden vernachlässigen wir die beiden Initialisierungen in den Zeilen 1 und 3. Für jeden Durchlauf i der Schleife (ab Zeile 2) haben wir also folgenden Aufwand: i Multiplikationen für die i-te Potenz in Zeilen 4 und 5 Beachten Sie dabei, dass die letzte Iteration für i = 0 diesen Schritt überspringt! 1 Multiplikation für den Koeffizienten in Zeile 6 1 Addition für die Summierung in Zeile 7 Damit kommen wir bei n + 1 Iterationen also auf folgenden Gesamt-Aufwand: Multiplikationen: ( n ) i + (n + 1) = i=1 Additionen: ( n(n + 1) 2 n + 1 ) + (n + 1) = 1 2 n2 + 3 2 n + 1 Die Laufzeitfunktion ist damit mindestens so groß wie die Summe dieser beiden Zahlen, da wir ja zusätzlichen Aufwand wie hauptsächlich die Schleifenverwaltung (vom Aufwand O(n)) ignorieren. Also folgern wir: T (n) = O(n 2 ) b) Dies bringt uns zur nächsten Implementierung, bei der die Berechnung der Potenz inkrementell über die Hilfsvariable h erfolgt: 1 p = 0; 2 h = 1; 3 for i = 0 to n { 4 m = a[i] h; 5 h = h x; 6 p = p + m; Auch hier vernachlässigen wir wieder die Initialisierungen in Zeilen 1 und 2. Für jeden Durchlauf der Schleife (ab Zeile 3) ergibt sich also:

6 1 Multiplikation für den Koeffizienten in Zeile 4 1 Multiplikation für die Potenzierung in Zeile 5 1 Addition für die Summierung in Zeile 6 Somit lässt sich also der Gesamt-Aufwand bei n + 1 Iterationen errechnen: Multiplikationen: 2(n + 1) = 2n + 2 Nachdem die Zeile 5 ganz am Schluss einmal zu oft ausgeführt wird, ließe sich der Aufwand um eine Multiplikation reduzieren. Außerdem liessen sich zwei weitere Multiplikationen vermeiden, da ja im ersten Durchlauf (mit h = 1) zwei überflüssige Multiplikationen mit 1 stattfinden. Die minimale Anzahl an Multiplikationen ist daher 2n 1. Additionen: n + 1 Die Laufzeitfunktion ist hier wieder mindestens so groß wie die Summe dieser beiden Zahlen, und wieder käme zusätzlicher Aufwand für die Schleifenverwaltung hinzu. Also: T (n) = O(n) c) Betrachten wir zuletzt das Horner-Schema: 1 p = a[n]; 2 for i = n 1 down to 0 { 3 p = p x; 4 p = p + a[i] Dieser Code ist vollständig optimiert und kann durch die Zuweisung in Zeile 1 eine komplette Schleifeniteration einsparen. In einem einzigen Durchlauf haben wir dabei folgenden Aufwand: 1 Multiplikation mit einem ausgeklammerten Faktor der Potenz in Zeile 3 1 Addition für die Summierung in Zeile 4 Bei nur n Iterationen ergibt sich also dieser Gesamtaufwand: Multiplikationen: Additionen: n n Wie zuvor ergibt sich die Laufzeitfunktion als Summe der beiden Zahlen und muss durch Schleifenverwaltungsaufwand der Größe O(n) ergänzt werden. Zusammen also: T (n) = O(n) d) Zuletzt waren die drei Implementationen zu vergleichen. Offensichtlich ist der naïve Ansatz wegen seiner O(n 2 ) Komplexität der eindeutige Verlierer gegen die beiden anderen Methoden. Interessanter ist dagegen der Vergleich zwischen inkrementeller Berechnung der Potenz und dem Horner-Schema, da beide ja in der gleichen Komplexitätsklasse O(n) sind. Wie Sie sich erinnern, unterscheiden sich die Elemente einer Komplexitätsklasse durchaus um konstante Faktoren, lediglich das generelle Wachstumsverhalten ist ab einer bestimmten Problemgröße vergleichbar. Insofern können zwei O(n) Lösungen doch unterschiedlich schnell sein, alleine der Beschleunigungsfaktor ist garantiert unabhängig von n.

7 Wenn man sich also auf die Zählung von Multiplikationen beschränkt die auf klassischen Systemen den größten Aufwand erzeugen, so wird das Horner-Schema mit seinen n Multiplikationen gegenüber der inkrementellen Berechnung mit ihren minimal 2n 1 Multiplikationen stets etwa doppelt so schnell sein. Damit ist im Hinblick auf Geschwindigkeitsoptimalität das Horner-Schema der eindeutige Gewinner.