REKURSION ITERATION Bemerkung Die in den folgenden Folien
REKURSION + ITERATION
Bemerkung: Die in den folgenden Folien angegebenen "Herleitungen" sind keine exakten Beweise, sondern Plausibilitätsbetrachtungen. Die exakten Beweise wurden dazu in einem anderen Dokument gemacht.
Eine Anwendung aus der Spieltheorie: Optimale Strategie bei einem Spiel.
Konkret: Kann man Schach, Dame, Mühle, usw. so spielen, daß man "immer" gewinnt?
Wir untersuchen diese Frage zuerst an einem "einfacheren" Spiel
Das Nimm-Spiel
Auf dem Tisch liegt ein Haufen von =5 anzahl Streichhölzern. Jeder Spieler muss eine Anzahl zwischen 1 und 3 Streichhölzern vom Tisch nehmen. Wer nicht mehr ziehen kann (weil kein Streichholz mehr da ist) hat verloren. Man kann das Spiel auch verallgemeinern: Statt maximal 3 Streichhölzer kann maximal k Streichhölzer nehmen.
Möglicher Spielverlauf: Spieler 1 zieht 2 Streichhölzer, also aktuelle Anzahl = 5 -2=3 Spieler 2 zieht 1 Streichholz, also aktuelle Anzahl = 3 -1=2 Spieler 1 zieht 2 Streichhölzer, also aktuelle Anzahl = 2 -2=0 wer hat verloren ? Spieler 2 hat verloren
Frage Wie geht das Spiel aus, wenn der anziehende und der nachziehende Spieler jeweils den "besten Zug" machen ?
5 Streichhölzer liegen auf einem Haufen. Erstellen Sie den dazugehörigen Spielbaum. (d. h. zeichnen Sie alle möglichen Spielverläufe ein). Hilfestellung: Siehe angefangenen Spielbaum auf der nächsten Folie. . .
5 2 4 3 0 1 0 2 1 2 3 0 01 0 1 2 0 0 Wichtig: 2, 3, 4 nennt man die Nachfolger von 5. 0, 1 nennt man die Nachfolger von 2, usw. 0 01 0
Gewinnermittlung: Wie geht das Spiel aus, wenn alle 2 Spieler optimal spielen ?
Wir beginnen bei den Blättern des Baums und notieren in jeder Position (Spielstellung), die durch einen Knoten dargestellt wird, die maximal mögliche Auszahlung (d. h. bei optimaler Spielweise) (1: Gewinn, -1: Niederlage) des Spielers, der gerade am Zug ist (des anziehenden Spielers):
Nochmals: Die Auszahlung (Payout, maximaler Gewinn) bezieht sich IMMER auf den anziehenden Spieler (= Spieler, der gerade am Zug ist)
Bemerkung: Man nennt dieses Spiel ein Nullsummenspiel, weil der Gewinn des einen (z. B. Auszahlung = 1) gleich dem Verlust (Auszahlung = -1) des anderen Spielers ist.
5 2 3 Dort wo die 0 vorkommt, hat der (anziehende) Spieler verloren, also Auszahlung = -1 4 0 1 2 1 2 3 -1 -1 0 0 0 1 0 1 2 -1 -1 -1 0 01 -1 -1 0 -1
5 2 3 4 0 1 2 1 2 3 -1 -1 0 0 0 1 0 1 2 -1 -1 -1 0 01 -1 -1 1 wenn hier verloren wurde, wie groß ist dann 0 die Auszahlung des davor ziehenden Spielers? -1
5 Dazu betrachten wir die jeweiligen maximal möglichen Auszahlungen, die A in den 3 möglichen nachfolgenden Positionen hat. Man kennt dort aber nur die maximalen Auszahlungen des Gegners: -1, 1 Wie hoch sind also die 3 maximale möglichen Auszahlungen von A? Welche davon ist die Größte? Beachten Sie, dass es sich um ein Nullsummenspiel handelt 2 3 4 0 1 2 1 2 -1 -1 --1, also 1, -1 Das Maximum ist 1. Deshalb wird A den Zug 0 0 1 0 (ganz rechts) machen, weil 1 dieser zur 0 maximalen -1 Auszahlung -1 führt: -1 max(--1, -1 -1)-1= 1 -1 0 0 -1 -1 Was ist hier der optimale Zug für den anziehenden Spieler A? max. Gewinn für A? 3 1 21 0 01 -1 -1 1 0 -1
5 max(--1) = 1 2 3 4 0 1 2 1 2 3 -1 -1 0 0 0 1 0 1 2 -1 -1 -1 1 1 0 01 -1 -1 1 Was ist hier der optimale Zug für den 0 anziehenden Spieler? Was ist sein max. Gewinn? -1
5 max(--1) = 1 2 3 4 0 1 2 1 2 3 -1 -1 0 0 0 1 0 1 -1 -1 -1 1 0 0 0 Was ist hier der optimale -1 1 1 Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 21 01 -1 1 0 -1
2 5 max(--1) = 1 3 4 0 1 2 1 2 3 -1 -1 0 0 0 1 0 1 -1 -1 -1 1 0 0 0 Was ist hier der optimale -1 1 1 Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 21 01 -1 1 0 -1
5 max(--1, -1) = 1 2 3 4 0 1 2 1 2 31 -1 -1 0 0 0 1 0 1 -1 -1 -1 1 0 0 0 -1 -1 -1 Was ist hier der optimale Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 21 01 -1 1 0 -1
5 max(--1, -1) = 1 2 3 4 0 1 2 1 21 31 -1 -1 0 0 0 1 0 1 -1 -1 -1 1 0 0 0 -1 -1 -1 Was ist hier der optimale Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 21 01 -1 1 0 -1
5 max(--1) = 1 2 4 3 0 1 2 -1 -1 0 0 0 1 -1 -1 -1 1 0 -1 11 21 0 01 0 -1 -1 0 -1 Was ist hier der optimale Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 31 1 2 1 1 0 01 -1 -1 1 0 -1
5 max(--1, -1) = 1 2 4 3 0 1 21 -1 -1 0 0 0 1 -1 -1 -1 1 0 -1 11 21 0 01 0 -1 -1 0 -1 Was ist hier der optimale Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 31 1 2 1 1 0 01 -1 -1 1 0 -1
5 max(--1) = 1 2 4 3 0 11 21 -1 -1 0 0 0 1 -1 -1 -1 1 0 -1 11 21 0 01 0 -1 -1 0 -1 Was ist hier der optimale Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 31 1 2 1 1 0 01 -1 -1 1 0 -1
5 max(--1) = 1 2 4 3 0 11 21 -1 0 0 0 1 -1 -1 -1 1 0 -1 11 21 0 01 0 -1 -1 0 -1 Was ist hier der optimale Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 31 1 2 1 1 0 01 -1 -1 1 0 -1
5 2 max(-1, -1) = -1 4 3 0 11 21 -1 0 0 0 1 -1 -1 -1 1 0 -1 -1 11 21 0 01 0 -1 -1 0 -1 Was ist hier der optimale Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 31 1 2 1 1 0 01 -1 -1 1 0 -1
5 2 max(--1, -1) = 1 4 3 -1 1 0 11 21 -1 0 0 0 1 -1 -1 -1 1 0 -1 11 21 0 01 0 -1 -1 0 -1 Was ist hier der optimale Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 31 1 2 1 1 0 01 -1 -1 1 0 -1
5 2 1 max(--1, -1) = 1 4 3 -1 1 0 11 21 -1 0 0 0 1 -1 -1 -1 1 0 -1 11 21 0 01 0 -1 -1 0 -1 Was ist hier der optimale Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 31 1 2 1 1 0 01 -1 -1 1 0 -1
51 2 1 4 3 -1 1 0 11 21 -1 0 0 0 1 -1 -1 -1 1 max(-1, --1) = 1 0 -1 11 21 0 01 0 -1 -1 0 -1 Was ist hier der optimale Zug für den anziehenden Spieler? Was ist sein max. Gewinn? 31 1 2 1 1 0 01 -1 -1 1 0 -1
Hier nochmals der allgemeine Zusammenhang als Formel
Die zwei Spielteilnehmer werden im Folgenden mit Spieler und Gegenspieler bezeichnet.
p 1 max, p 2 max, p 3 max bezeichne die maximalen Auszahlungen des Gegenspielers bei allen möglichen Nachfolgepositionen (Nachfolgeknoten) Wie berechnet man daraus die maximale Auszahlung pmax des Spielers beim Vorgängerknoten?
Da es sich um Nullsummenspiel handelt, sind die Gewinne des einen die Verluste des anderen. D. h. wenn die Auszahlungen des Gegenspielers sind: p 1 max, p 2 max, p 3 max sind sie für den Spieler: -p 1 max, -p 2 max, -p 3 max. Welche Auszahlung ist für den Spieler dann am Größten?
Natürlich das Maximum davon, also: pmax = max(-p 1 max, -p 2 max, -p 3 max).
Man kann dieses Prinzip der Rekursion (für die entsprechenden Beispiele) ganz allgemein durch einen Baum darstellen:
ein Spielstand (hier Anzahl der Streichhölzer), dessen maximaler Gewinn w = N(a) berechnet werden soll a, N(a) Dazu zerlegt man ihn in seine Bestandteile (nachfolgende Spielstände a 1, a 2, a 3), d. h. bildet die Nachfolger im Baum gilt für a ≥ 3 a-1, N(a-1) a-2, N(a-2) a-3, N(a-3) . . . und tut dann so, als ob die maximalen Gewinne w 1=N(a-1), w 2=N(a-2) und w 3=N(a-3) der Nachfolger a-1, a-2, a-3 bekannt wären. Wie kann man dann den maximalen Gewinn w = N(a) durch die maximalen Gewinne N(a-1), N(a-2) und N(a-3) berechnen? N(a) = Maximum (-N(a-1), -N(a-2), -N(a-3))
(a, N(a)) Das 2. Element im Tupel ist der Nachbar des 1. Elements, also der Nachbar von a. Er wird hier deshalb mit N (wie Nachbar) bezeichnet. (a-1, N(a-1)) ( a-2, N(a-2)) ( a-3, N(a-3) ) N(a) = Maximum (-N(a-1), -N(a-2), -N(a-3)) Rekursion: N kommt links und rechts des Gleichheitszeichens vor! Des Weiteren: Hier handelt es sich nicht um einzelne Werte, sondern um 2 er-Pakete (Zweier-Tupel), die man mathematisch wie folgt darstellt. . .
Berechnung des maximalen Gewinns (Auszahlung) bei einem Haufen von a Streichhölzern durch eine Regelmenge
Erzeugung der Regeln: Regelmenge, mit denen man die Haufen (Anzahl der Streichhölzer) einschließlich ihrer maximalen Gewinne induktiv definieren kann.
-----(0, -1) -----(1, 1) -----(2, 1) Regel 1, kurz R 1 (Atom) wenn 0 Streichhölzer da sind, hat der anziehende Spieler verloren Regel 2, kurz R 2 (Atom) Bei einem Haufen mit 1 Streichholz nimmt der anziehende Spieler 1 Streichholz weg, dann hat er gewonnen (unabhängig vom Zug des nachfolgenden Spielers). Regel 3, kurz R 3 (Atom) Bei einem Haufen mit 2 Streichhölzern nimmt der anziehende Spieler 2 Streichhölzer weg, dann hat er gewonnen (unabhängig vom Zug des nachfolgenden Spielers).
4, kurz R 4 {(a-1, w 1), (a-2, w 2), (a-3, w 3)} Regel wobei a ≥ 3 -------------------(a, max(-w 1, -w 2, -w 3)) abgekürzt: {(a-1, w 1), (a-2, w 2), (a-3, w 3)} -------------------(a, g(w 1, w 2, w 3))
Aufgabe: Geben Sie die Mengen D 0, D 1, D 2 an.
D 0 =
Jetzt zur Berechnung von D 2:
{(a-1, w 1), (a-2, w 2), (a-3, w 3)} -------------------(a, g(w 1, w 2, w 3)) angewendet auf: was gibt g(-1, 1, 1), also max(1, -1) = 1 {(0 , -1), ( 1 , 1 ), (2 , 1 )} -----------------(3 , g(-1, 1 ))
Jetzt zur Berechnung von D 3:
{(a-1, w 1), (a-2, w 2), (a-3, w 3)} -------------------(a, g(w 1, w 2, w 3)) angewendet auf: was gibt g(1, 1, 1), also max(-1, -1) = -1 {(1 , 1 ), ( 2 , 1 ), (3 , 1 )} --------------(4 , g(1 , 1 ))
Wie früher gilt: D = D 0 D 1 D 2 D 3 . . .
Also: Wie kann N(a) rekursiv berechnet werden …?
Wie berechnet man N(z), wobei z die 1. Komponente eines Atoms (Tupel) ist ? Also z. B. N(0) = -1 weil (0, -1) ein Atom ist N(1) = 1 weil (1, 1) ein Atom ist N(2) = 1 weil (2, 1) ein Atom ist
Wie kann dann N(a) berechnet werden, wenn a nicht 1. Komponente eines Atoms ist, also a ≥ 3 ist?
Wie vorher kann man wieder die Kandidatenmenge angeben, d. h. die Menge der Kandidaten, die z. B. die eine Menge von 8 Streichhölzern produziert haben könnten. K(8) = {(5, 6, 7)}
Angenommen, man will N(8) berechnen und man wüsste den maximalen Gewinn bei der Anzahl von 5, 6 und 7 Streichhölzern, also die Werte N(5) , N(6) und N(7) wären bekannt. Wie wird dann N(8) berechnet?
Indem man das Maximum von -N(5) , -N(6) und -N(7) berechnet, also: N(8) = max(-N(5) , -N(6) , -N(7))
Aufgabe: Erstellen Sie die Funktion N(int anz), die im Nimm-Spiel den maximalen Gewinn des anziehenden Spielers berechnet.
#include "stdafx. h" int max(int z 1, int z 2, int z 3); int N(int anz); int main(){ int erg; int i; for(i=0; i<20; i++){ erg = N(i); printf("i= %d erg =%d n", i, erg); } return 0; }
int max(int z 1, int z 2, int z 3){ int maxi; if(z 1<z 2) maxi=z 2; else maxi=z 1; if(z 3>maxi) maxi=z 3; return maxi; }
int N(int anz){ int max. Gewinn; if (anz==0) max. Gewinn = -1; else if(anz==1) max. Gewinn = 1; else if(anz==2) max. Gewinn = 1; else max. Gewinn= max(-N(anz-3), -N(anz-2), -N(anz-1)); return max. Gewinn; }
Weiteres Beispiel für eine Rekursion bzw. Regelmenge
Berechnung des Werts einer Zeichenkette bzw. Terms
Alle folgenden Zeichenketten sollen aus dem Alphabet A= {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) , ( , + , - } bestehen. D. h. eine beliebige Zeichenkette darf nur aus diesen Zeichen bestehen. Die Menge aller Terme, die aus dem Alphabet A hergestellt werden, bezeichnen wir mit X.
Unter einem mathematischen Term verstehen wir hier einen aus den Rechenzeichen + bzw. -und den Ziffern bzw. den Klammern zusammengesetzten Ausdruck. Also:
1) Die Zeichen von 0 bis 9 2) Zeichenketten der Form: (9+2), ((3 -2)+3), ((5+7)+((4+(6 -6))), usw.
Welche Werte haben die folgenden Zeichenketten bzw. Terme?
3+-7 45 (8 -9 7 (9 -2) ((3 -2)+3) ((5+7)+((4+(6+6))) Diese Zeichenkette ist kein Term. Zahlen sind keine Terme (außer Ziffern). Dies ist kein Term. 7 ist eine Ziffer, also ein Term und soll den Wert 7 haben Dies ist ein Term und hat den Wert 7 Dies ist ein Term und hat den Wert 4 Term mit Wert 28
Bemerkung: Eigentlich müsste man z. B. zwischen dem Term 7 und dem Wert 7 dieses Terms unterscheiden (unterschiedliche Bezeichnungen), also Term: "7" (also eine Zeichenkette) Wert: 7 (also eine Zahl) Dies wird hier aus Gründen der Vereinfachung nicht gemacht.
Erzeugung der Regeln: (Regelmenge), mit denen man Terme einschließlich ihrer Werte induktiv definieren kann.
Dies unterscheidet sich etwas in der Notation zu früher. Warum ?
Früher bestand ein Element nur aus z. B. einem Term. Jetzt ist es ein Term und ein Wert. Dies wird durch einen Zweier-Tupel (kurz: Tupel) dargestellt.
Hat eine Zeichenkette keinen Wert, also keine Zahl (weil sie kein Term ist), wird dieser Wert mit # dargestellt. Ein Tupel beginnt mit der Klammer ( und endet mit der Klammer ) Die Klammern, die bei der Termerzeugung - wie z. B. (3+5) benötigt werden, werden im Gegensatz dazu mit schwarzer Farbe dargestellt.
(3+7, ? ) (4 -5, ? ) ((3 -9, ? ) (2, ? ) ((9+2), ? ) (((3+2)-3), ? ) (((5+7)+(4+(6+6))), ? ) Für welche Werte stehen die Fragezeichen ?
(3+7, #) (4 -5, #) ((3 -9, #) (2, 2) ((9+2), 11) (((3+2)-3), 2) (((5+7)+(4+(6+6))), 28) Zeichenkette (kein Term) mit Wert # Term 2 mit Wert 2 Term (9+2) mit Wert 11 Term ((3+2)-3) mit Wert 2 Term. . . mit Wert 28
Aufgabe: Geben Sie die Regeln (Regelmenge) an, mit denen man Terme induktiv definieren, d. h. exakt formalisieren kann.
-----(0, 0). . . -----(9, 9) -------(z, #) Regel 1, kurz R 1 Regel 10, kurz R 10 R 1 bis R 11 sind die Regelaxiome. Regel 11, kurz R 11 wobei z X und z ist kein Term. Der Wert # bedeutet, daß z kein Term ist.
Regel 12, kurz R 12 wobei T 1 ein Term aus X und T 2 auch ein Term aus X ist und w 1 und w 2 ganze Zahlen sind. {(T 1, w 1); (T 2, w 2)} --------------((T 1+T 2), add(w 1, w 2)) add(w 1, w 2) bedeutet die Summe von w 1 und w 2. Warum schreibt man dann nicht einfach w 1+w 2 ? Weil das + schon für die Termbildung verwendet wird und dort einfach nur ein Zeichen bedeutet. Ganz wichtig: T 1 und T 2 sind Terme !!
Regel 13, kurz R 13 wobei T 1 ein Term aus X und T 2 auch ein Term aus X ist und w 1 und w 2 ganze Zahlen sind. {(T 1, w 1); (T 2, w 2)} --------------((T 1 -T 2), sub(w 1, w 2)) sub(w 1, w 2) bedeutet die Differenz von w 1 und w 2. Warum schreibt man dann nicht einfach w 1 -w 2 ? Weil das - schon für die Termbildung verwendet wird und dort einfach nur ein Zeichen bedeutet. Ganz wichtig: T 1 und T 2 sind Terme !!
Aufgabe: Geben Sie die Mengen D 0, D 1, D 2 an.
D 0 =
D 1 = { (0, 0); . . . ; (9, 9) } {(z, #) | z X z ist kein Term}
oder in beschreibender Mengenschreibweise:
D 2 = { (1, 1) ; . . . ; (9, 9) } {((d 1+d 2), add(d 1, d 2)) | d 1 Z und d 2 Z} { (1, 1) ; . . . ; (9, 9) } {((d 1 -d 2), sub(d 1, d 2)) | d 1 Z und d 2 Z} {(z, #) | z X z ist kein Term} wobei Z = {0, 1, . . . , 9}
Wie früher gilt: D = D 0 D 1 D 2 D 3 . . .
Uns interessiert nun die 2. Der Nachbar von 7 Komponente eines Tupels, also den Wert, d. h. den Nachbar eines Terms, Der Nachbar von (9+2) also z. B: (7, 7) man schreibt: Der Nachbar von ((3+2)+3) N(7) = 7 ((9+2), 11) man schreibt: N( (9+2) ) = 11 (((3+2)+3), 8) man schreibt: N( ((3+2)+3) ) = 8
Wie kann N(z) rekursiv berechnet werden …?
Wie vorher kann man wieder die Kandidatenmenge angeben, d. h. die Menge der Kandidaten, die z. B. die Zeichenkette ((1+2)+(3+4)) produziert haben könnten. K(((1+2)+(3+4))) = {(1+2) , (3+4)} Beachte: Regel R 12 verlangt, daß die zerlegten Zeichenketten Terme sein müssen.
Angenommen, man will N(((1+2)+(3+4))) berechnen und man wüsste den Wert von (1+2) und von (3+4), also die Werte N((1+2)) und N((3+4)) wären bekannt. Wie wird dann N(((1+2)+(3+4))) berechnet?
wobei dieses + das mathematische Zeichen für die Addition ist Indem man die Werte N((1+2)) und N((3+4)) addiert, also: N(((1+2)+(3+4))) = add(N((1+2)), N((3+4)))
Wie berechnet man N(z), wobei z die 1. Komponente eines Atoms (Tupel) ist, wie z. B. N(6) ?
Indem man einfach die 2. Komponente des Atoms nimmt! Beispiele: N(6) = 6 N(3++)+a) = # weil (6, 6) D 1 weil (3++)+a, #) D 1
Insgesamt ergibt dies die folgende mathematische Formel:
// Kandidatenmenge leer: Fall: K(x) = ==> N(z) = #, falls z kein Term N(z) = z, falls z eine Ziffer // x kommt direkt nach dem Urknall: Fall: K(T) ={(T 1, T 2)} ==> N(T) = gi(N(T 1), N(T 2)) wobei gi eine Funktion ist (wie z. B. add oder sub), die von T abhängt.
Weniger mathematisch kann man dieses Prinzip der Rekursion (für die entsprechenden Beispiele) auch durch einen Baum darstellen.
ein Term, dessen Wert w = N(T) berechnet werden soll T, N(T 2) Dazu zerlegt man ihn in seine Bestandteile (Terme T 1 und T 2 ), d. h. bildet die Nachfolger im Baum Frage: Welcher Zusammenhang besteht dann zwischen T, T 1 und T 2? T 1, N(T 1) T 2 , N(T 2) T = (T 1+T 2) oder T = (T 1 -T 2) . . . und tut dann so, als ob die Werte w 1=N(T 1) und w 2=N(T 2) der Nachfolger T 1 und T 2 bekannt wären. Wie kann man dann den Wert w = N(T) durch den Wert N(T 1) von T 1 und den Wert N(T 2) berechnen? in Abhängigkeit der Zerlegung (T 1+T 2) oder (T 1 -T 2) gilt dann: N(T) = add(N(T 1), N(T 2)) oder N(T) = sub(N(T 1), N(T 2))
Beispiel
((5+(6 -7))+8) 12 N( ((5+(6 -7))+8) ) = add(N((5+(6 -7))), N(8)) = 12 (5+(6 -7)) , 8 4 N((5+(6 -7))) = add(N(5), N((6 -7))) == 4 5 , (6 -7) 5 -1 N(5) = 5 8 N(8) = 8 N((6 -7)) = sub(N(6), N(7)) = -1 6 , 7 6 N(6) = 6 7 N(7) = 7 Wie groß ist jeweils N(…), d. h. welchen Wert haben die roten Blätter ?
Also: Wie kann N(z) rekursiv berechnet werden …?
Zuerst braucht man eine Funktion, die feststellt, ob eine Zeichenkette ein Term ist. Das ist die von früher bekannte Funktion e. Rek(. . ). Zusätzlich soll diese Fuktion noch (falls die Zeichenkette ein Term ist) die 2 Teilterme zurückliefern, in die der Terme zerlegt wurde.
- Slides: 105