PI Christoph Schnörr Übungsblatt 10 Wintersemester 2007/08 Jörg Kappes CVGPR-Gruppe, Universität Heidelberg Jan Lellmann Übungsblatt 10 Weihnachtsübungsblatt Aufgabe 1 [6P] (O-Kalkül Eigenschaften) Zeigen oder widerlegen Sie folgende Aussagen: a) f (n) < g(n) ∀n ∈ N ⇒ f (n) ∈ o(g(n)). b) f (n) ≤ g(n) ∀n ∈ N ⇔ O(f (n)) ⊆ O(g(n)). c) Für beliebige a, b ∈ R, b > 0 gilt (n + a)b ∈ O(nb ). d) f (n) ∈ O(g(n)), g(n) ∈ O(f (n)) ⇒ f (n) ∈ Θ(g(n)). e) f (n) ∈ O(h(n)), g(n) ∈ O(h(n)), a, b ≥ 0 ⇒ af (n) + bg(n) ∈ O(h(n)). f) O(2n ) = O(3n ). Aufgabe 2 (O-Kalkül Interpretation) a) [1.5P] Θ Geben Sie zu jeder der folgenden Funktionen eine möglichst einfache Laufzeitklasse in - Notation an (ohne Beweis): n2 + 2n − 4 2n + n 2 min{2n , 2008n2 } 26n+logn 2n3 + 4n2 + 8n + 16 (n + 4)4 log(nn+2 ) b) [0.5P] Ein Softwarehersteller wirbt mit der Aussage Die Laufzeit unseres Verfahrens beträgt mindestens c) [1.5P] Θ(n2 ) O(n2 ). Würden Sie das Produkt kaufen (mit Begründung)? Sie haben zwei Verfahren zur Auswahl, eines mit Laufzeitklasse Laufzeitklasse Θ(n2 ) und eines mit 3 Θ(n ). Reicht diese Information zur Auswahl des für Ihre Anwendung schnelleren Verfahrens? Falls nicht, welche Informationen werden zusätzlich benötigt? Aufgabe 3 (Laufzeitklasse Fibonacci) F ib(n) ∈ O(1.62n ) gezeigt. Im Folgenden Berechnung von F ib(n) bestimmt werden. In der Vorlesung wurde bereits den Aufwand der rekursiven Dazu wird das bekannte Schema 2), n > 1 verwendet. Mit Berechnung von F ib(n) f (n) F ib(0) = 1, F ib(1) = 1 werde die Anzahl der und soll eine Beziehung für F ib(n) = F ib(n − 1) + F ib(n − Additionen bezeichnet, die auf diese Weise zur benötigt werden (das Subtrahieren von Konstanten vom Index n zähle hier nicht als Addition). a) [1P] Stellen Sie eine Rekursionsgleichung für f (n) auf. Gehen Sie von f (0) = f (1) = 0 aus. b) [1.5P] Zeigen Sie mittels vollständiger Induktion: f (n) ∈ O(2n ). c) [1P] Berechnen Sie f (n) n. Vergleichen Sie mit den Werten von F ib(n) und stellen f (n) mit Hilfe der Fibonacci-Funktion darstellen lässt. für einige Sie eine Behauptung auf, wie sich 1/5 PI Christoph Schnörr Übungsblatt 10 Wintersemester 2007/08 Jörg Kappes CVGPR-Gruppe, Universität Heidelberg Jan Lellmann d) [2P] Beweisen Sie Ihre Behauptung durch vollständige Induktion. e) [1P] Betrachten Sie folgenden alternativen Code zur Berechnung von F ib(n): fib[n_] := Module[{a = 0, b = 1, t}, Do[t = b; b += a; a = t, {n}]; a]; Bestimmen Sie die exakte Anzahl Additionen eine möglichst einfache Komplexitätsklasse (in g(n) zur Berechnung von f ib(n) Θ - Notation) für g(n) an. und geben Sie Aufgabe 4 [4P] Richtig oder Falsch Beweisen oder widerlegen Sie folgende Aussagen. a) Im IEEE-754-Standard sind alle reellen Zahlen zwischen 1 und 2 darstellbar. b) Die Menge der im IEEE-754-Standard darstellbaren Zahlen ist bzgl. Addition und Multiplikation abgeschlossen. c) Die kleinste nichtnegative darstellbare normalisierte Zahl im IEEE-754-Standard ist gröÿer als 0. d) Folgende zwei in hexadezimaler Darstellung angegebenen Kodierungen stellen die gleiche Zeichenfolge dar. (UTF-32) 000000F600000012000051A2 (UTF-8) C3B612E586A2 Aufgabe 5 (Kodierung von Zahlen) a) [2P] Ein Zahlensystem ist ein Tripel S = (b, Σ, δ). Für die Basis b = 3 sei die Menge der Symbole Σ = {0, 1, 2}. Für die anderen Basen nden Sie die Denitionen auf den Vorlesungsfolien. Die Abbildung δ bildet jede Zier auf die entsprechende natürliche Zahl ab. Eine Ausnahme bilden die Symbole A bis F, die auf 10 bis 15 abgebildet werden. Ergänzen Sie folgende Tabelle: Basis Zahlen 2 3 8 10 16 1011012 2103 2718 4210 2B16 b) [2.5P] In der Vorlesung haben Sie mehrere Festkommadarstellungen zur Basis 2 kennengelernt. Ergänzen Sie die folgende Tabelle. <a> 60 Vor-.Nachkommastellen [a]BV [a]EK 8.0 10011101 00101010 8.0 10101010 8.0 9.375 [a]ZK 8.0 5.3 2/5 PI Wintersemester 2007/08 Christoph Schnörr Übungsblatt 10 Jörg Kappes CVGPR-Gruppe, Universität Heidelberg Jan Lellmann c) [2P] In der Vorlesung wurde die Gleitkommadarstellung nach IEEE 754 vorgestellt. Teilen Sie die IEEE 754-Gleitkommazahl 11000101011101101010000000001000 in Vorzeichenbit, Mantisse und Exponent auf und geben Sie den dezimalen Wert der Zahl an (mit Rechenweg). Handelt es sich um eine Zahl einfacher oder doppelter Genauigkeit? Geben Sie die Zahl -19 in IEEE 754-Darstellung mit einfacher Genauigkeit an. Geben Sie alle möglichen Darstellungen für 0,−∞,+∞ und NaN im IEEE 754-Format (ein- fache Genauigkeit) an. Aufgabe 6 (Labyrinth in Mathematica für Fortgeschrittene) Sie haben sich ja bereits als Meister des Labyrinthes bewiesen. Jetzt soll die Suchstrategie verbessert werden. Bisher wurde der Pfad mit Breiten- und Tiefensuche gefunden. Die Frage ist, ob es Algorithmen gibt, die weniger Knoten besuchen muessen, um einen Pfad von s nach t zu nden (wir betrachten hier nicht den zurückgelegten Weg). Die Idee um dies zu erreichen ist naheliegend: Wenn Sie sich in einem Labyrinth benden, wissen wo Sie hin möchten und noch nicht total die Orientierung verloren haben werden Sie in der Regel zuerst den Weg einschlagen, von dem Sie vermuten, dass er Sie näher zu Ihrem Ziel bringt. a) [0.5P] Implementieren Sie eine Funktion, die für einen Punkt im Labyrinth eine Bewertung abgibt, wie gut diese Position im Hinblick auf das gegebene Ziel ist. Tipp: Überlegen sie sich wie sich wie weit ist das Ziel noch weg mathematisch formulieren lässt. b) [2P] Modizieren Sie den Breiten- bzw. Tiefensuchenalgorithmus so, dass zuerst der Pfad mit der besten Bewertung weiterverfolgt wird. Die Bewertungsfunktion soll dem BestFirstSearch- Algorithmus als Parameter übergeben werden. c) [0.5P] Schreiben Sie eine Bewertungsfunktion, mit der sich der Algorithmus wie ein TiefensucheAlgorithmus verhält. d) [0.5P] Schreiben Sie eine Bewertungsfunktion, mit der sich der Algorithmus wie ein BreitensucheAlgorithmus verhält. e) [0.5P] Modizieren Sie ihren Code so, dass die Anzahl der besuchten Knoten protokolliert wird. f) [1.5P] Finden Sie für jeden der drei Algorithmen einen Fall, in dem der Algorithmus mit weniger besuchten Knoten als die anderen eine Lösung ndet. Variieren Sie dazu den RandomSeed sowie den Start- und Endknoten. Der Abstand zwischen den beiden Knoten sollte aber mindestens 5 betragen. Wenn einer der Algorithmen die anderen beiden unter keinen Umständen schlagen kann begründen Sie warum. g) [1P] Erzeugen Sie eine hinreichend groÿe Menge zufälliger Graphen sowie Anfangs- und End- knoten und bestimmen Sie experimentell für jeden der drei Algorithmen einen Erwartungswert für die Anzahl besuchter Knoten. Vergleichen Sie die Ergebnisse. Aufgabe 7 (Zeiger als Rückgabewerte) a) [1P] Hugo H. hat wirklich kein Glück: Er hat in einem C++ - Kurs von Zeigern gehört und ist begeistert er liebt die Gefahr. Um seine neu erworbenes Wissen zu testen, hat er folgendes Programm geschrieben: #include <stdlib.h> 3/5 PI Übungsblatt 10 Wintersemester 2007/08 Christoph Schnörr Jörg Kappes CVGPR-Gruppe, Universität Heidelberg Jan Lellmann #include <iostream> using namespace std; int* addiere(int a, int b) { int summe = 0; summe = a + b; return &summe; } int main() { int* pi = addiere(4,1); cout << *pi << endl; return (EXIT_SUCCESS); } Leider funktioniert das Programm überhaupt nicht. Helfen Sie ihm, indem Sie den Fehler nden und erklären. b) [0.5P] Hugo hat aus der letzten Teilaufgabe gelernt und seine Funktion ersetzt: int* addiere(int a, int b) { int* psumme = new int; *psumme = a + b; return psumme; } Das Programm funktioniert und Hugo ist stolz. Zurecht? Warum? new int reserviert int* zurück. Hinweis: Der Ausdruck einen Zeiger des Typs c) [0.5P] Speicher für eine Variable des Typs int und liefert Geben Sie einen Fall an, in dem es (im Gegensatz zu den vorherigen Teilaufgaben) sinnvoll oder sogar notwendig ist, einen Zeiger anstatt eines Wertes zurückzuliefern. Aufgabe 8 (Klasse in C++) Wie Sie in einer der früheren Aufgaben gesehen haben ist das Arbeiten mit Feldern in C++ fehleranfällig, da man beim Zugri unbeabsichtigt auf Elemente auÿerhalb des Feldes zugreifen kann. Auÿerdem sind Kopieren und Vergleichen umständlich. In dieser Aufgabe soll eine Klasse Felder mit Elementen des Typs int Array für implementiert werden, die diese Nachteile nicht hat. Die Klassendeklaration soll folgendermaÿen aussehen (Sie nden den Code auf unserer Webseite unter cpp_oo_feld.cpp): class Array { private: int* data; // Hier wird der Zeiger auf das eigentliche Feld gespeichert int size; public: Array(int _size); ~Array(); int getSize(); void set(int index, int value); 4/5 PI Christoph Schnörr Übungsblatt 10 Wintersemester 2007/08 Jörg Kappes CVGPR-Gruppe, Universität Heidelberg Jan Lellmann int get(int index); }; void copyFrom(const Array& other); bool equals(const Array& other); a) [1P] Implementieren Sie den Konstruktor. Die Anweisung Array a(10); soll ein neues Objekt erzeugen, das ein Feld mit mit 0 10 Elementen repräsentiert. Die Elemente sollen initialisiert werden. b) [1P] Implementieren Sie den Destruktor. Warum ist der Destruktor hier unbedingt notwendig? c) [1P] Implementieren Sie die Methode getSize sowie die Methoden set und get zum Zugri auf einzelne Feldelemente. Wenn ein ungültiger Index übergeben wurde, soll das Programm mit dem Befehl error(<Fehlermeldung>); abgebrochen werden. d) [1P] Bei der Zuweisung Array a(10); Array b(10); a = b; werden alle Attribute des Objekts b in das Objekt a kopiert. Warum ist das in diesem Fall nicht erwünscht, sondern sogar gefährlich? e) [0.5P] Implementieren Sie die Methode copyFrom zum Kopieren der Werte aus einem anderen gleichgroÿen Array. Warum ist die Übergabe als konstante Referenz hier sinnvoll? f) [0.5P] Implementieren Sie die Methode equals. Die Methode soll genau dann true zurück- liefern, wenn beide Felder die gleiche Gröÿe haben und der Feldinhalt identisch ist. Hinweis: Felder können in C++ nicht direkt mit == verglichen werden, sie benötigen also eine Schleife und einen elementweisen Vergleich. Abgabe: Bis Freitag, 11.01.2008, 12:00 Uhr. Abgabe in 2er- oder 3er-Gruppen. Die Kästen für den Einwurf stehen in Gebäude INF 308 auf der Südseite (links neben HS 2) und sind nach Tutorien sortiert. Quellcode und Mathematica-Notebooks bitte ebenfalls ausdrucken und nach Absprache zusätzlich per Mail an den jeweiligen Tutor schicken. Eine rein elektronische Abgabe ist nicht möglich. Auf diesem Blatt sind mehr als die üblichen 20 Punkte zu erreichen. Zum Erreichen der vollen Punktzahl genügen 20 Punkte, alle weiteren Punkte sind Bonuspunkte und werden mit nicht erreichten Punkten auf anderen Übungsblättern verrechnet. Vorlesungsbeginn im neuen Jahr ist der der 8.1.2008, das erste Tutorium ndet bereits am 7.1. statt. Wir wünschen allen Hörern frohe Weihnachten und einen guten Rutsch ins neue Jahr! 5/5