Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 8: Akkumulation von.

Ähnliche Präsentationen


Präsentation zum Thema: "Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 8: Akkumulation von."—  Präsentation transkript:

1 Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 8: Akkumulation von Wissen Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

2 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Rekursive Funktionen Die rekursiven Funktionen, die wir bisher gesehen haben, sind kontextfrei –Sie kümmern sich um ihr Subproblem, ohne etwas von dem Gesamtproblem zu wissen Vorteil: Solche Funktionen sind einfach zu entwickeln, einfach wartbar etc. Nachteil: Manche Funktionen werden dadurch ineffizient oder kompliziert 2

3 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Beispiel Gegeben: Liste von Punkten mit relativer Distanz zwischen Punkten Aufgabe: Absolute Distanzen vom Ursprung berechnen

4 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Lösung mit struktureller Rekursion 4 ;; relative-2-absolute : (listof number) -> (listof number) ;; to convert a list of relative distances to a ;; list of absolute distances; the first item on the list ;; represents the distance to the origin (define (relative-2-absolute alon) (cond [(empty? alon) empty] [else (cons (first alon) (add-to-each (first alon) (relative-2-absolute (rest alon))))])) ;; add-to-each : number (listof number) -> (listof number) ;; to add n to each number on alon (define (add-to-each n alon) …)

5 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Lösung mit struktureller Rekursion Bevor wir die Nachteile diskutieren, wollen wir kurz unser Wissen über Funktionen höherer Ordnung anwenden –(add-to-each n alon) -> (map (lambda (m) (+ n m)) alon)) –(relative-2-absolute alon) -> (foldr (lambda (x xs) (cons x (add-to-each x xs))) empty alon)) Beachte: die Funktion, die gefaltet wird, ist nicht assoziativ –foldl anstelle von foldr ergibt ein anderes Ergebnis! –Wie kommt man auf die letzte Gleichung? 5 ;; add-to-each : number (listof number) -> (listof number) ;; to add n to each number in alon (define (add-to-each n alon) (cond [(empty? alon) empty] [else (cons (+ (first alon) n) (add-to-each n (rest alon)))]))

6 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Zur Erinnerung: foldr Wie kann man foldr spezialisieren, um relative-2-absolute zu erhalten? f = (lambda (x xs) (cons x (add-to-each x xs))) 6 ;; foldr : (X Y -> Y) Y (listof X) -> Y ;; (foldr f base (list x-1... x-n)) = ;; (f x-1... (f x-n base)) (define (foldr f base alox) (cond [(empty? alox) base] [else (f (first alox) (foldr f base (rest alox)))])) (define (relative-2-absolute alon) (cond [(empty? alon) empty] [else (cons (first alon) (add-to-each (first alon) (relative-2-absolute (rest alon))))]))

7 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Zurück zum Thema… Was ist die Zeitkomplexität von relative-2-absolute in Abhängigkeit von der Länge der Liste? Sei T(n) Zeitkomplexität von relative-2-absolute, sei U(n) Zeitkomplexität von add-to-each U(n) = 1 + U(n-1) U(n) = n O (n) T(n) = 1 + T(n-1) + U(n-1) = 1 + T(n-1) + n-1 = n + T(n-1) = n + (n-1) + … + 1 = n*(n+1) / 2 = (n 2 +n)/2 O (n ² ) In der Version mit foldr, map kann man die Zeitkomplexität leicht aus der Zeitkomplexität von foldr, map folgern –foldr f base alox T(n) = n* (n), – wobei n = Länge von alox, – (n) = Zeitkomplexität von f 7

8 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Was ist das Problem? Das Problem ist die Kontextfreiheit von relative-2- absolute –Der rekursive Aufruf für L in der Liste (cons N L) macht genau dasselbe wie bei einer anderen Liste (cons K L) Idee: Zusätzlicher Parameter akkumuliert das Wissen über den Kontext, in diesem Fall die akkumulierte Distanz 8 (define (rel-2-abs alon accu-dist) (cond [(empty? alon) empty] [else (cons (+ (first alon) accu-dist) (rel-2-abs (rest alon) (+ (first alon) accu-dist)))]))

9 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Lösung Funktion ist noch nicht äquivalent zu relative-2- absolute –Es gibt einen zusätzlichen Parameter –Dieser ist am Anfang 0 9 (define (relative-2-absolute2 alon) (local ((define (rel-2-abs alon accu-dist) (cond [(empty? alon) empty] [else (cons (+ (first alon) accu-dist) (rel-2-abs (rest alon) (+ (first alon) accu-dist)))]))) (rel-2-abs alon 0)))

10 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Beispiel mit generativer Rekursion Das Problem, in bestimmten Situationen Wissen zu akkumulieren, existiert nicht nur bei struktureller, sondern auch bei generativer Rekursion Beispiel: Finden von Pfaden in einem einfachen Graphen, in dem jeder Knoten nur eine ausgehende Kante hat (Zyklen sind erlaubt!). 10 (define SimpleG '((A B) (B C) (C E) (D E) (E B) (F F))) Ein Knoten ist ein Symbol. Ein Paar ist eine Liste mit zwei Knoten (mit S, T Symbole): (list S T) Ein simple-graph ist eine Liste von Paaren: (listof pair). ABCDEF

11 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Beispiel mit generativer Rekursion Der Kopf der Funktion ist einfach Für die Implementierung des Körpers brauchen wir Antworten zu den 4 Basisfragen bei generativer Rekursion: –Was ist ein trivial zu lösendes Problem? Das Problem ist trivial, wenn die Knoten orig und dest den selben Knoten bezeichnen –Was ist eine dazugehörige Lösung? Einfach: true. –Wie erzeugen wir neue Probleme? Wenn orig nicht denselben Knoten wie dest bezeichnet, können wir folgendes tun: gehe zu den Knoten, mit denen orig verbunden ist und stelle fest, ob diese eine Verbindung mit dest haben. –Wie verbinden wir die Lösungen? Wir müssen nichts mehr tun, wenn wir das neue Problem gelöst haben. Wenn orig s Nachbar mit dest verbunden ist, gilt das auch für orig. 11 ;; route-exists? : node node simple-graph -> boolean ;; to determine whether there is a route from ;; orig to dest in sg (define (route-exists? orig dest sg)...)

12 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Die Lösung ist nun einfach… …funktioniert aber leider nicht richtig! –route-exists? kann nie false zurückgeben 12 ;; route-exists? : node node simple-graph -> boolean ;; to determine whether there is a route from orig to dest in sg (define (route-exists? orig dest sg) (cond [(symbol=? orig dest) true] [else (route-exists? (neighbor orig sg) dest sg)])) ;; neighbor : node simple-graph -> node ;; to determine the node that is connected to a-node in sg (define (neighbor a-node sg) (cond [(empty? sg) (error "neighbor: impossible")] [else (cond [(symbol=? (first (first sg)) a-node) (second (first sg))] [else (neighbor a-node (rest sg))])]))

13 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Ursache des Fehlers Betrachten wir einen Fall, in dem false zurückgegeben werden müsste: Die Funktion ruft sich nach ein paar Aufrufen wieder mit denselben Parametern auf –Endlosschleife Ursache: Die Funktion vergisst, mit welchen Parametern sie schon aufgerufen wurde 13 (route-exists? 'C 'D '((A B) (B C) (C E) (D E) (E B) (F F))) = (route-exists? 'E 'D '((A B) (B C) (C E) (D E) (E B) (F F))) = (route-exists? 'B 'D '((A B) (B C) (C E) (D E) (E B) (F F))) = (route-exists? 'C 'D '((A B) (B C) (C E) (D E) (E B) (F F))) = … ABCDEF

14 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Lösung Akkumulation der besuchten Knoten Akkumulation alleine reicht nat ü rlich nicht aus, wir müssen das akkumulierte Wissen auch nutzen! 14 ;; route-exists-accu? : ;; node node simple-graph (listof node) -> boolean ;; to determine whether there is a route from orig to dest in sg, ;; assuming the nodes in accu-seen have already been inspected ;; and failed to deliver a solution (define (route-exists-accu? orig dest sg accu-seen) (cond [(symbol=? orig dest) true] [else (route-exists-accu? (neighbor orig sg) dest sg (cons orig accu-seen))]))

15 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Lösung Check hinzufügen, spezialisieren… 15 ;; route-exists2? : node node simple-graph -> boolean ;; to determine whether there is a route from orig->dest in sg (define (route-exists2? orig dest sg) (local ((define (re-accu? orig dest sg accu-seen) (cond [(symbol=? orig dest) true] [(contains? orig accu-seen) false] [else (re-accu? (neighbor orig sg) dest sg (cons orig accu-seen))]))) (re-accu? orig dest sg empty)))

16 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Vorläufige Zusammenfassung Sowohl strukturelle als auch generative Rekursion können von dem Problem betroffen sein, dass man einen Akkumulator benötigt –Bei dem Beispiel mit struktureller Rekursion haben wir die Performanz erheblich verbessert –Das Beispiel mit generativer Rekursion funktionierte ohne Akkumulator nicht Betrachten wir nun im Allgemeinen, wann man einen Akkumulator benötigt. 16

17 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Entwurf von Funktionen mit Akkumulatoren Oft erkennt man, dass man einen Akkumulator benötigt, erst nachdem man bereits eine Version der Funktion implementiert hat… Der Schlüssel zur Entwicklung einer Funktion im Akkumulator-Stil ist: –Erkenne, dass die Funktion einen Akkumulator benötigt, oder von dessen Verwendung profitiert; –Verstehe, was den Akkumulator ausmacht. 17

18 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Erkennen, dass man einen Akkumulator benötigt Wir haben zwei Gründe gesehen: –Performanz –Die Funktion funktioniert ohne Akkumulator nicht korrekt. Das sind die wichtigsten Gründe um Akkumulator- Parameter hinzuzufügen. In beiden Fällen ist es entscheidend, dass wir zunächst eine vollständige Funktion auf Basis eines Design Musters entwerfen. Dann studieren wir diese Funktion und schauen nach den folgenden Eigenschaften… 18

19 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Potentieller Kandidat für Akkumulator Heuristik: Die Funktion ist strukturell rekursiv Ergebnis einer rekursiven Anwendung wird durch eine zusätzliche, rekursive Funktion bearbeitet 19 ;; invert : (listof X) -> (listof X) ;; to construct the reverse of alox ;; structural recursion (define (invert alox) (cond [(empty? alox) empty] [else (make-last-item (first alox) (invert (rest alox)))])) ;; make-last-item : X (listof X) -> (listof X) ;; to add an-x to the end of alox ;; structural recursion (define (make-last-item an-x alox) (cond [(empty? alox) (list an-x)] [else (cons (first alox) (make-last-item an-x (rest alox)))]))

20 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Funktionen im Akkumulator-Stil Wenn wir entschieden haben, eine Funktion im Akkumulator-Stil zu schreiben, führen wir den Akkumulator in zwei Schritten hinzu 1.Definition und Bereitstellung des Akkumulators –Welches Wissen über die Parameter muss im Akkumulator gespeichert werden? Für relative-2-absolute reichte es aus, die gesamte bisherige Distanz zu akkumulieren (Akkumulator = eine Zahl) Für das Routenproblem mussten wir jeden Knoten, der bisher besucht wurde, speichern (Akkumulator = eine Liste von Knoten) 2.Ausnutzung des Akkumulators 20

21 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Definition und Bereitstellung des Akkumulators Füge ein Template der Akkumulatorfunktion als lokale Funktion ein. Benenne die Parameter der Hauptfunktion und der Hilfsfunktion unterschiedlich. 21 ;; invert : (listof X) -> (listof X) ;; to construct the reverse of alox (define (invert alox0) (local (;; accumulator... (define (rev alox accumulator) (cond [(empty? alox)...] [else (rev (rest alox)... (first alox)... accumulator)... ]))) (rev alox0...)))

22 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Analyse invert kann nichts vergessen, da es nur die Reihenfolge von Listenelementen ändert. Daher könnten wir einfach alle Elemente akkumulieren denen rev begegnet. Das bedeutet: –accumulator steht für eine Liste und –accumulator steht für alle Elemente in alox, die dem alox- Argument von rev vorangehen. –Der Anfangswert von accumulator ist leer. –Wenn rev rekursiv aufgerufen wird, hat es nur ein Element bearbeitet: (first alox). Um uns an dieses Element zu erinnern, können wir es mittels cons an die aktuellen Liste accumulator einf ü gen. 22

23 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Erweiterte Version von invert accumulator enthält nicht einfach die Elemente von alox0 vor alox, sondern eine Liste dieser Elemente in umgekehrter Reihenfolge. 23 ;; invert : (listof X) -> (listof X) ;; to construct the reverse of alox (define (invert alox0) (local (;; accumulator is the reversed list of all those items ;; on alox0 that precede alox (define (rev alox accumulator) (cond [(empty? alox) …] [else …(rev (rest alox) (cons (first alox) accumulator)) …]))) (rev alox0 empty)))

24 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Ausnutzen des Akkumulators accumulator ist die Liste aller Elemente von alox0 vor alox in umgekehrter Reihenfolge… Sobald alox leer ist, enth ä lt accumulator die Umkehrung von alox0. 24 ;; invert : (listof X) -> (listof X) ;; to construct the reverse of alox (define (invert alox0) (local (;; accumulator is the reversed list of all those items ;; on alox0 that precede alox (define (rev alox accumulator) (cond [(empty? alox) accumulator] [else (rev (rest alox) (cons (first alox) accumulator))]))) (rev alox0 empty)))

25 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 [Direkte Implementierung von invert] Variante ohne Akkumulator… 25 ;; invert : (listof X) -> (listof X) ;; to construct the reverse of alox (define (invert alox) (cond [(empty? alox) empty] [else (append (invert (rest alox)) (list (first alox)))]))

26 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Definition von Akkumulator-Invarianten Im Allgemeinen beschreibt eine Akkumulator-Invariante einen Beziehung zwischen –dem eigentlichen Argument der Funktion, –dem aktuellen Argument der Hilfsfunktion, und –dem Akkumulator Wir betrachten die Definition von Akkumulator-Invarianten an einem Beispiel, welches keinen Akkumulator benötigt –Ermöglicht genauen Vergleich der beiden Varianten Beispiel: Addition aller Zahlen einer Liste 26 ;; sum : (listof number) -> number ;; to compute the sum of the numbers in alon ;; structural recursion (define (sum alon) (cond [(empty? alon) 0] [else (+ (first alon) (sum (rest alon)))]))

27 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Definition von Akkumulator-Invarianten Erster Schritt zu einer Akkumulator-Variante: Template Ziel von sum ist die Summation von Zahlen Intuitive Akkumulator-Invariante: Akkumulator speichert die Summe der Zahlen, die schon bearbeitet wurden 27 ;; sum : (listof number) -> number ;; to compute the sum of the numbers on alon0 (define (sum alon0) (local (;; accumulator... (define (sum-a alon accumulator) (cond [(empty? alon)...] [else... (sum-a (rest alon)... (first alon)... accumulator)... ]))) (sum-a alon0...)))

28 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Definition von Akkumulator-Invarianten Erster Schritt zu einer Akkumulator-Variante: Template 28 ;; sum : (listof number) -> number ;; to compute the sum of the numbers in alon0 (define (sum alon0) (local (;; accumulator is the sum of the numbers ;; in alon0 that preced those in alon (define (sum-a alon accumulator) (cond [(empty? alon)...] [else... (sum-a (rest alon) (+ (first alon) accumulator))... ]))) (sum-a alon0 0)))

29 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Definition von Akkumulator-Invarianten Der Rest ist nun einfach Der Schlüssel ist die präzise Definition der Akkumulator- Invariante, der Rest folgt dann von selbst. 29 ;; sum : (listof number) -> number ;; to compute the sum of the numbers on alon0 (define (sum alon0) (local (;; accumulator is the sum of the numbers ;; in alon0 that preceeded those in alon (define (sum-a alon accumulator) (cond [(empty? alon) accumulator] [else (sum-a (rest alon) (+ (first alon) accumulator))]))) (sum-a alon0 0)))

30 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Vergleich Ursprüngliche Version Akkumulator-Version 30 (sum (list )) = ( (sum (list ))) = ( ( (sum (list 5.27)))) = ( ( ( (sum empty)))) = ( ( ( ))) = ( ( )) = ( ) = 20.0 (sum (list )) = (sum-a (list ) 0) = (sum-a (list ) 10.23) = (sum-a (list 5.27) 14.73) = (sum-a empty 20.0) = 20.0

31 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T8 Zusammenfassung Manche Funktionen sind nur im Akkumulator-Stil korrekt zu implementieren –Beispiel: route-exists? In anderen Fällen führt der Akkumulator-Stil zu einem Effizienzgewinn –Beispiel: relative-2-absolute Es ist jedoch nicht so, dass Funktionen im Akkumulator- Stil immer schneller sind –Beispiel: sum Wir werden später sehen, dass Funktionen im Akkumulator-Stil sehr ähnlich zu Schleifen in Sprachen wie Java, Pascal etc. sind 31


Herunterladen ppt "Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 8: Akkumulation von."

Ähnliche Präsentationen


Google-Anzeigen