Lösungsvorschlag Serie 2 Rekursion

Ähnliche Dokumente
Algorithmen & Programmierung. Rekursive Funktionen (1)

Einführung in die Informatik I

Prof. Dr. Margarita Esponda

Komplexität von Algorithmen

Dynamische Programmierung. Problemlösungsstrategie der Informatik

Der Dreyfus-Wagner Algorithmus für das Steiner Baum Problem

Rekursive Funktionen

12. Rekursion Grundlagen der Programmierung 1 (Java)

Speicher und Adressraum

Rekursion. Sie wissen wie man Programme rekursiv entwickelt. Sie kennen typische Beispiele von rekursiven Algorithmen

Technische Informatik 1 Übung 2 Assembler (Rechenübung) Georgia Giannopoulou (ggeorgia@tik.ee.ethz.ch) 22./23. Oktober 2015

Programmieren in C. Rekursive Funktionen. Prof. Dr. Nikolaus Wulff

Einstieg in die Informatik mit Java

Einschub: Anweisungen und Bedingungen für PAP und Struktogramme (1)

Funktionale Programmierung. Funktionale Programmierung: Vorlesungsüberblick. Eigenschaften rein funktionaler Programmierung

Übung zur Vorlesung Berechenbarkeit und Komplexität

Großübung zu Einführung in die Programmierung

Kapitel 5: Dynamisches Programmieren Gliederung

Informatik I: Einführung in die Programmierung

Student: Alexander Carls Matrikelnummer: Aufgabe: Beschreibung des euklidischen Algorithmus Datum:

Projekt Systementwicklung

Komplexität von Algorithmen

Funktionale Programmiersprachen

Datenstrukturen und Algorithmen

Es ist für die Lösung der Programmieraufgabe nicht nötig, den mathematischen Hintergrund zu verstehen, es kann aber beim Verständnis helfen.

Kapitel 5: Abstrakte Algorithmen und Sprachkonzepte. Elementare Schritte

Grundlagen der Programmierung WS 15/16 (Vorlesung von Prof. Bothe)

Babeș-Bolyai Universität Cluj Napoca Fakultät für Mathematik und Informatik Grundlagen der Programmierung MLG5005. Paradigmen im Algorithmenentwurf

Ideen und Konzepte der Informatik. Programme und Algorithmen Kurt Mehlhorn

Programmierkurs Python I

Schnittstellen, Stack und Queue

Babeș-Bolyai Universität Cluj Napoca Fakultät für Mathematik und Informatik Grundlagen der Programmierung MLG5005. Rekursion

Funktionale Programmierung ALP I. Funktionen höherer Ordnung. Teil 2 SS Prof. Dr. Margarita Esponda. Prof. Dr.

Kapiteltests zum Leitprogramm Binäre Suchbäume

11. Rekursion, Komplexität von Algorithmen

Dynamische Programmierung

JAVA - Rekursion

Imperative vs. Funktionale Programmierung

Abstrakte Algorithmen und Sprachkonzepte

Grundlagen der Informatik I (Studiengang Medieninformatik)

Programmieren lernen mit Groovy Rekursion Rekursion und Iteration

Dynamisches Programmieren - Problemstruktur

Übersicht. 4.1 Ausdrücke. 4.2 Funktionale Algorithmen. 4.3 Anweisungen. 4.4 Imperative Algorithmen Variablen und Konstanten. 4.4.

Algorithmen und Datenstrukturen Tafelübung 4. Jens Wetzl 15. November 2011

Ü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:

To know recursion, you must first know recursion. Borchers: Programmierung für Alle (Java), WS 06/07 Kapitel 17 1

Programmieren I. Methoden-Special Heusch --- Ratz 6.1, Institut für Angewandte Informatik

Klausur Informatik 1 SS 08. Aufgabe Max. Punkte Punkte. Gesamtpunkte:

Übersicht. Datenstrukturen und Algorithmen Vorlesung 5: Rekursionsgleichungen (K4) Übersicht. Binäre Suche. Joost-Pieter Katoen. 20.

In C und Java müssen Variablen und Methodenergebnisse durch Typangaben erläutert werden. Welche der folgenden Aussagen sind korrekt und welche nicht:

Inhalt. 1. Einführung in die Informatik. 2. Algorithmen Definition, Eigenschaften, Entwurf Darstellung von Algorithmen Beispiele.

Einführung in die Informatik I

Grundlagen der Programmierung

Schwerpunkte. Verkettete Listen. Verkettete Listen: 7. Verkettete Strukturen: Listen. Überblick und Grundprinzip. Vergleich: Arrays verkettete Listen

Binäre lineare Optimierung mit K*BMDs p.1/42

Rekursion. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Nachklausur Bitte in Druckschrift leserlich ausfüllen!

Effiziente Algorithmen und Datenstrukturen I. Kapitel 10: Lineare Algebra

Programmiertechnik Methoden, Teil 2

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen

Grundlagen der Programmierung

Lösungsvorschlag zu 1. Übung

2. Algorithmenbegriff

Crashkurs Haskell Mentoring WiSe 2016/17. Anja Wolffgramm Freie Universität Berlin

Rekursive Auswertungsprozesse in Haskell

Algorithmen und Datenstrukturen 1. EINLEITUNG. Algorithmen und Datenstrukturen - Ma5hias Thimm 1

Typdeklarationen. Es gibt in Haskell bereits primitive Typen:

Programmierung in Python

Kostenmaße. F3 03/04 p.188/395

Einführung in Mathematica

Effiziente Algorithmen

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen

Programmierung 2. Dynamische Programmierung. Sebastian Hack. Klaas Boesche. Sommersemester

Einführung in die Funktionale Programmierung mit Haskell

Einstieg in die Informatik mit Java

Matrikelnr. Name. Vorname

3. Binäre Suchbäume. 3.1 Natürliche binäre Suchbäume. EADS 3.1 Natürliche binäre Suchbäume 78/598 ľernst W. Mayr

Übung: Algorithmen und Datenstrukturen SS 2007

Programmiertechnik II

Counting - Sort [ [ ] [ [ ] 1. SS 2008 Datenstrukturen und Algorithmen Sortieren in linearer Zeit

Rekursive Algorithmen

II.3.1 Rekursive Algorithmen - 1 -

Der Euklidische Algorithmus

Datenstrukturen und Algorithmen

Java: Eine kurze Einführung an Beispielen

11. Elementare Datenstrukturen

Übersicht. Datenstrukturen und Algorithmen. Übersicht. Divide-and-Conquer. Vorlesung 9: Quicksort (K7)

Viel Spaÿ! Aufgabe 0.1. Laufzeit unter Verdoppelung (-)

Noch für heute: primitive Datentypen in JAVA. Primitive Datentypen. Pseudocode. Dezimal-, Binär- und Hexadezimalsystem. der logische Typ boolean

Programmieren ++ Begleitende Übungen zu Veranstaltungen + Umsetzen des Algorithmus in ein lauffähiges Programm

Beispiellösung zu den Übungen Datenstrukturen und Algorithmen SS 2008 Blatt 5

AK-Automatisierungs und Kommunikationstechnik TI Technische Informatik. NWT Netzwerktechnik

2.2 Allgemeine (vergleichsbasierte) Sortierverfahren

Differenzengleichungen. und Polynome

Technische Universität Braunschweig Institut für Programmierung und Reaktive Systeme

SOI Die Schweizer Informatikolympiade

Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung)

Beispiel: Fibonacci-Zahlen

Informatik B von Adrian Neumann

= 7 (In Binärdarstellung: = 0111; Unterlauf) = -8 (In Binärdarstellung: = 1000; Überlauf)

Transkript:

(/) Lösungsvorschlag Serie Rekursion. Algorithmen-Paradigmen Es gibt verschiedene Algorithmen-Paradigmen, also grundsätzliche Arten, wie man einen Algorithmus formulieren kann. Im funktionalen Paradigma werden Berechnungen durch Funktionen formuliert. Damit lassen sich natürlich v.a. mathematische Funktionen sehr einfach ausdrücken. Es gibt Programmiersprachen, in welchen sich Algorithmen dieses Paradigmas unverändert implementieren lassen (z.b. Haskell). Die Fibonacci-Funktion wird funktional wie folgt definiert: fib(0) = fib() = fib(n) = fib(n ) + fib(n ) Algorithmen gemäss dem imperativen Paradigma bilden die verbreitetste Art, Algorithmen für Computer zu formulieren, da sie auf einem abstrakten Modell eines üblichen Rechners basieren. Imperative Algorithmen basieren auf den Konzepten Anweisung und Variable. Dabei werden die Befehle in einer genau definierten Reihenfolge abgearbeitet. Das imperative Paradigma wird durch viele Programmiersprachen wie C, C++, COBOL und auch Java realisiert. Da Maschinenprogramme für übliche Rechner schlussendlich auch imperativ sind, folgt daraus, dass z.b. in funktionalen Programmiersprachen implementierte Programme letztlich auch in imperative übersetzt werden. Es ist deshalb üblich, Algorithmen gemäss dem imperativen Paradigma zu formulieren. Man sollte insbesondere darauf achten, die verschiedenen Konzepte nicht zu vermischen. (a) fib(n) als imperativer Algorithmus (rekursiv) Der Pseudocode für den imperativen Algorithmus könnte folgendermassen aussehen: int Algorithm fib(n): // Output: Fibonacci Zahl von n // Zweck : Rekursive Berechnung der Fibonacci-Zahl if n < then return return (fib(n-) + fib(n-)) (b) Wie sich die Rekursion zur Laufzeit entfaltet, lässt sich Abbildung entnehmen. Kommentar: Dieser rekursive Algorithmus zur Berechnung von f ib(n) stellt sich zur Laufzeit als sehr aufwändig und ineffizient (exponentielle Komplexität) heraus. Immer wieder werden Ausdrücke erneut berechnet (z. B. fib()), deren Resultat eigentlich bereits ausgerechnet wurde. Es werden also sehr viele redundante Berechnungen vorgenommen.

(/) fib() fib() fib() fib(0) 8 fib() fib(4) fib() fib() fib() fib() fib() fib(0) fib() fib(0) fib() fib(6) fib() fib() fib(4) fib() fib() fib() fib() fib(0) fib(0) Abbildung : Dynamische Entfaltung der Rekursion fib(6).

(/) (c) Es ist möglich, den Algorithmus so in einen rekursiven Algorithmus umzuformulieren, dass er eine lineare Zeitkomplexität aufweist: fib(n) als imperativer Algorithmus (endrekursiv) Der rekursive Algorithmus mit linearer Zeitkomplexität ist endrekursiv. int Algorithm linrecfib(n, a, a): // Output : Fibonacci Zahl von n // Zweck : Iterative Berechnung der Fibonacci-Zahl if n==0 return a linrecfib(n-, a, a+a) Dieser Algorithmus ist gleich effizient wie der nachfolgend vorgestellte iterative Algorithmus. fib(n) als imperativer Algorithmus (iterativ) int Algorithm iterativfib(n): // Output : Fibonacci Zahl von n // Zweck : Iterative Berechnung der Fibonacci-Zahl a = b = result = for (i=; i<=n; i++) result = a + b b = a a = result return result fib(n) explizit berechnet Bisher mussten wir zur Berechnung einer Fibonacci-Zahl alle vorhergehenden Zahlen berechnen. Der französische Mathematiker Jacques-Philippe-Marie Binet hat bereits 84 eine Funktion gefunden, mit welcher sich eine beliebige Fibonacci-Zahl explizit berechnen lässt: f(n) = ( + ) n+ ( ) n+. (a) Der rekursive Algorithmus zur Berechnung von sum(n) kann wie folgt aussehen: Algorithm sum(n): // Input : ganze Zahl n>= // Output: Summe von bis n if n== then return return n + sum(n-) (b) Die rekursive Implementation von sum(n) unter a) ist eine lineare, direkte Rekursion, die nicht endrekursiv ist (als letzte Operation wird die Addition ausgeführt).

(4/) (c) Der iterative Algorithmus zur Berechnung von sum(n) kann wie folgt aussehen: int Algorithm sum(n): // Input : ganze Zahl n>= // Output: Summe von bis n sum = 0 for i= to n do sum = sum + i return sum. (a) Die Lösung ist in Abbildung dargestellt. y 4 0 6 7 8 4 0 0 4 x Abbildung : Die gefüllte Figur Nachstehend ist die Reihenfolge der rekursiven Aufrufe aufgeführt. Dabei gibt die Zahl rechts die momentane Rekursions- bzw. Stacktiefe an. Flood_Fill(,) Flood_Fill(,) Flood_Fill(4,) Flood_Fill(,) 4 Flood_Fill(,) 4 Flood_Fill(4,4) 4 Flood_Fill(4,) 4 Flood_Fill(,) Flood_Fill(,) Flood_Fill(4,) Flood_Fill(4,) Flood_Fill(,) 6 Flood_Fill(,) 6 Flood_Fill(4,) 6 Flood_Fill(4,0) 6 Flood_Fill(,) Flood_Fill(,4) Flood_Fill(,) Flood_Fill(,) Flood_Fill(,) Flood_Fill(0,) Flood_Fill(,4) Flood_Fill(,) Flood_Fill(,) 4 Flood_Fill(0,) 4 Flood_Fill(,) 4 Flood_Fill(,) 4

(/) Flood_Fill(,) Flood_Fill(,) 6 Flood_Fill(,) 6 Flood_Fill(,) 6 Flood_Fill(,0) 6 Flood_Fill(0,) Flood_Fill(,) Flood_Fill(,0) Flood_Fill(,4) Flood_Fill(,) (b) Die maximale Rekursions- bzw. Stacktiefe beträgt 6. (c) Beurteilung des Algorithmus: Es handelt sich um einen höchst ineffizienten Algorithmus. Für nur 9 Punkte braucht man schon einen Stack der Tiefe 6 und es kommt zu 7 Funktionsaufrufe. Der Algorithmus füllt i. Allg. nur dann die ganze Figur, wenn die Stacktiefe nicht begrenzt wird. Wird diese aber nicht begrenzt, so kann es zu einem Speicherüberlauf kommen. Es gibt auch Varianten des Flood-Fill-Algorithmus, die die Stacktiefe begrenzen und im Fall von Löchern den Algorithmus in diesen Löchern wieder starten. Das Auffinden dieser Löcher ist aber schwierig.