Effiziente Algorithmen VU 2.0 186.144 — WS 2005/06 Übungsblatt 1: 10. Jänner 2006 Aufgabe 1: Ein Profiler ist ein Hilfsprogramm zur Ermittlung von Kenndaten zum Ablauf von Programmen. Insbesondere kann man ermitteln, wie oft bestimmte Zeilen des Programms durchlaufen werden, und die Laufzeit bestimmen, die in verschiedenen Programmteilen verbraucht wird. Stellen Sie das Grundprinzip solcher Profiler anhand praktischer Beispiele dar und recherchieren Sie, welche Implementierungen für gängige Programmiersprachen es derzeit auf dem Markt gibt. Aufgabe 2: Gegeben seien eine Menge von n reellen Zahlen, eine reelle Zahl t, und eine natürliche Zahl k < n. Wie schnell können Sie ermitteln, ob es eine Untermenge von k Zahlen aus der Gesamtmenge gibt, deren Summe nicht größer als t ist? Es gibt Algorithmen mit Laufzeiten O(nk), O(n2), O(n k), O(n log n) und O(n log k). Geben Sie für möglichst viele dieser Laufzeiten passende Algorithmen an! Hinweis: Es wird nur nach der Existenz einer solchen Untermenge gefragt, aber nicht unbedingt nach ihren Elementen. (Nett wäre es natürlich schon…) Aufgabe 3: Recherchieren Sie, welche gängigen Algorithmen zur softwaremäßigen Ermittlung von Pseudo-Zufallszahlen es gibt. Stellen Sie mindestens zwei dieser Algorithmen mit ihren jeweiligen Vor- und Nachteilen dar. Recherchieren Sie außerdem, welche gängigen Möglichkeiten zur Ermittlung von echten (!) Zufallszahlen es gibt. Behandeln Sie mindestens zwei Hardwarebasierte Lösungen, aber auch mindestens eine Software-basierte (!) Variante. Vergessen Sie nicht, auch auf den ungefähren Aufwand (algorithmisch und finanziell) der jeweiligen Lösungen einzugehen. Aufgabe 4: Die assoziativen Arrays von AWK erzeugen keine definierte Reihenfolge, wenn man Strings als Indizes verwendet und danach mittels „for (i in array)“ durchläuft. Dennoch ist AWK eine allgemeine Programmiersprache, also kann man damit (hoffentlich) auch sortieren. Implementieren Sie ein Sortierprogramm in AWK, mit dessen Hilfe die Zeilen einer Eingabedatei lexikalisch aufsteigend sortiert werden können. Hinweis: Eine Laufzeit O(n log n) wäre sehr erfreulich. Gehen Sie bei Ihrer Argumentation zum Aufwand davon aus, dass Zugriffe auf assoziative Arrays in konstanter Zeit ausgeführt werden können (bei beschränkter Stringlänge, denn sonst wären sie wegen der Auswertung der Hashfunktion von dieser abhängig). Aufgabe 5: Eine Datei enthält eine Million reelle Zahlen und kann nur sequentiell gelesen werden. Entwerfen Sie einen möglichst effizienten Algorithmus, der unter Verwendung von möglichst wenig Platz im Hauptspeicher (weniger als 7 Zahlen!) den Median dieser unsortierten Datei findet, ohne diese zu verändern oder weitere Dateien anzulegen. (Es gibt einen Algorithmus, der Laufzeit O(n log n) hat.) Entwerfen Sie nun einen möglichst effizienten Algorithmus, der das gleiche Problem löst, wenn auch weitere (temporäre) Dateien angelegt werden dürfen. (Nun existiert eine Lösung mit Laufzeit O(n).) Aufgabe 6: Beschreiben Sie das Verfahren der arithmetischen Kodierung im Detail und veranschaulichen Sie die Kompression und Dekompression anhand eines geeigneten Beispiels. Welche Vor- bzw. Nachteile hat die arithmetische Kodierung im Vergleich zur Kompression mittels Huffman-Code? Zeigen Sie die Unterschiede anhand eines anschaulichen Beispiels. Aufgabe 7: Ein relativ neuer und viel versprechender Kompressionsalgorithmus trägt den Namen „bzip2“. Recherchieren Sie (z.B. in Wikipedia), wie dieser Algorithmus funktioniert. Erklären Sie die Funktionsweise theoretisch und mithilfe möglichst gut gewählter Beispieldaten. Aufgabe 8: Das Ziv-Lempel-Kompressionsverfahren auf Basis von LZSS kann mit Hilfe von Suffix-Trees effizient implementiert werden. Beschreiben Sie den LZ-Algorithmus unter Verwendung von Suffix-Trees, zeigen Sie ein Beispiel dafür und stellen Sie das Verfahren dem ursprünglichen LZ-Algorithmus gegenüber. Aufgabe 9: Wie kann der Suffix-Tree-Algorithmus von Ukkonen zur Textkompression verwendet werden, wenn der Text zu Beginn noch nicht vollständig bekannt ist? Welche Anwendungen gibt es in der Bioinformatik für den LZ-Algorithmus? Aufgabe 10: Das Problem, alle Vorkommen einer Menge von Patterns in einem Text zu finden (exaktes Set-Matching-Problem) kann mittels Keyword-Tree (Aho-CorasickMethode) oder mit Hilfe von Suffix-Trees effizient gelöst werden. Stellen Sie beide Verfahren vor und vergleichen Sie die Aufwände für Pre-processing und Suche. Aufgabe 11: Sich wiederholende Teilsequenzen (repetitive Strukturen, repeats) spielen in der Bioinformatik bei der Untersuchung von DNA, RNA und Proteinen eine bedeutende Rolle. Erklären Sie die folgenden Probleme und beschreiben Sie, wie diese sich mit Hilfe von Suffix-Trees lösen lassen. Verwenden Sie dazu anschauliche Beispiele. a) Problem des Auffindens aller maximalen repetitiven Strukturen. b) Problem des Auffindens aller supermaximalen repetitiven Strukturen. Aufgabe 12: Die TU Wien will ein neues Feature für ihre Telefonanlage implementieren: Man soll durch Eintippen von „*“ und den ersten fünf Buchstaben des Familiennamens einer Person (mit Hilfe der Buchstaben auf der Telefontastatur, z.B. 7 steht für PQRS) direkt zur richtigen Nebenstelle verbunden werden. Für Prof. Raidl wählt man dann also z.B. „*72435“. Skizzieren Sie geeignete Datenformate und Algorithmen (z.B. als Pseudocode oder in AWK) zur Erstellung einer Liste von Rufnummern aus einer Namensliste und zum Ermitteln der Person(en) zu einer gewählten Rufnummer (d.h. dem Vorgang, der beim Wählen in der Telefonanlage ablaufen muss). Diese Zuordnung muss ja nicht unbedingt eindeutig sein, sei es wegen öfter vorkommender Namen oder wegen der Abbildung mehrerer Buchstaben auf jeweils eine einzige Zifferntaste. Besprechen Sie daher auch das Auffinden von möglichen Konfliktfällen und mögliche Strategien zur Auflösung solcher Konflikte. Gehen Sie dabei gegebenenfalls auch auf sinnvolle Möglichkeiten zur Interaktion zwischen anrufender Person und Telefonanlage ein.