einfache Rekursionen - ?· Weitere einfache Rekursionen Bis jetz haben wir direkte Rekursionen kennengelernt,…

  • View
    212

  • Download
    0

Embed Size (px)

Transcript

Nach dem umfangreichen Beispiel "Trme von Hanoi" geht es jetz mit Rekursionen aus der

Mathematik weiter.

Die Berechnung der Fakultt einer natrlichen Zahl n

Dieses Problem lt sich iterativ leicht lsen. Will man n! berechnen, kann man das mit folgender

Methode leicht bewerkstelligen:

public int nFak(int n){int ergebnis=1;for(int i= 1;i

Die Methode "lebt" in vierfacher Ausfhrung mit jeweils unterschiedlichen Werten der Varia-

blen. Die letzte Aufrufebene hat die krzeste Lebensdauer und gibt ihr Ergebnis dann an die h-

here Aufrufebene zurck, deren Leben wiederum mit der Weitergabe des Ergebnisses beendet ist

u.s.w.

Noch einmal die Darstellung mit Programmbefehlen, Stack und Werten am Beispiel 4!

Das Programm verzweigt in der Befehlszeile 2 legt die Werte auf dem Stack ab und ruft sich

selbst wieder auf. Bei der Rckkehr aus Aufrufebene 4 wird das Ergebnis mitgenommen und

fhrt dann in der Aufrufebene 3 zur Beendigung der Programmzeile 2. Da es eine if ... then ... else

Konstuktion ist, geht es danach in Programmezeile 5 weiter ( Ende ) und die Abarbeitung findet

in der Aufrufebene 2 ihre Fortsetzung.

Wir formulieren diese Lsung in einem kleinen Javaprogramm und lassen sie fr verschiedene

Werte von n laufen.

Seite 22

Fakultt

Hans-Georg Beckmann 2004

Programm- Aufrufebene 1schritt

1 wenn ( n > 1)nFak(4)

2345

sonst ergebnis=4*nFak(3)

Endeergebnis=1

Rckspr.Adresse ergebnis n

Stack-pointer

Mitte 2 4* --- 4

Stack

Programm- Aufrufebene 2schritt

1 wenn ( n > 1)nFak(3)

2345

sonst ergebnis=3*nFak(2)

Endeergebnis=1

Rckspr.Adresse ergebnis n

Stack-pointer

Mitte 2Mitte 2

3* --- 34* --- 4

Programm- Aufrufebene 3schritt

1 wenn ( n > 1)nFak(2)

2345

sonst ergebnis=2*nFak(1)

Endeergebnis=1

Rckspr.Adresse ergebnis n

Stack-pointer

Mitte 2Mitte 2Mitte 2

2* ---3* ---

23

4* --- 4Programm- Aufrufebene 4schritt

1 wenn ( n > 1)nFak(1)

2345

sonst ergebnis=2*nFak(1)

Endeergebnis=1

Rckspr.Adresse ergebnis n

Stack-pointer

Mitte 2Mitte 2Mitte 2

2* 1=23* ---

23

4* --- 4er

gebn

is=

2*1

erge

bnis

=3*

2*1

erge

bnis

=4*

3*2*

1

Virtuelle Lehrerfortbildung imFach Informatik in Niedersachsen

//// Fakul1.java// n-Fakultt rekursiv gelst// VLIN 32 H.-G.Beckmann, 8/02

import java.awt.*;import java.applet.*;

public class Fakul1 extends Applet { int n; // die Zahl n public void init() { setLayout(null);

}// Ende von init public void paint (Graphics g) { n=6; // z.B. n=6 g.drawString(" Die Fakultt von "+n +" ist " + nFak(n),40,20); } // Ende von paint //*************************************************// Die rekursive Methode//************************************************* public int nFak (int n) { if(n>1) // Abbruchbedingung { return(n*nFak(n-1));} else { return 1;} }// Ende von nFak} // Ende von Applet

Man sieht, dass in der rekursiven Methode zuerst die Abbruchbedingung steht und dann - ohneweitere Variablen zu verwenden - direkt das Ergebnis an die aufrufende Programmebene mit return ... zurckgegeben wird.

Aufgabe:

Mit Variablen vom Typ int ist bei 13! schon kein korrek-

tes Ergebnis mehr zu erhalten. Stellen sie auf den Typ

long um, und testen sie, wie weit man damit richtige Er-

gebnisse bekommen kann. Ihr Tascherechner kann ih-

nen dabei als Kontrolle dienen

Seite 23

Fakultt

Hans-Georg Beckmann 2004Virtuelle Lehrerfortbildung imFach Informatik in Niedersachsen

Weitere einfache Rekursionen

Bis jetz haben wir direkte Rekursionen kennengelernt, bei denen eine Methode sich selbst auf-

ruft. Nun sollen an einfachen beispielen indirekte Rekursionen gezeigt werden, bei denen eine

Methode A in einer anderen Methode B und die wiederum in einer Methode C u.s.w aufgerufen

wird, die am Ende mglicherweise wieder von Methode A aufgerufen wird.

In der theoretischen Informatik spielen die primitiv - rekursiven Funktionen bei Berechenbar-

keitsuntersuchungen eine wichtige Rolle.

Man nehme als Basisfunktion die Nachfolgefunktion N(x) = x+1; Sie ordnet jeder ganzen natr-

lichen Zahl einen Nachfolger zu, den wir durch Addition von 1 erhalten.

(Die beiden anderen Basisfunktionen sind die Konstantenfunktion und die Projektion, auf die hier noch nicht eige-

gangen wird.)

Damit kann man nun eine Funktion SUM(x,y) definieren, die rekursiv auf dier Nachfolgefunkti-

on beruht, denn es ist mglich, die Summe x+y dadurch zu erhalten , dass man von x ausgehend

sooft den Nachfolger sucht, wie es y angibt.

Diese Definition muss man per Hand probieren:

SUM(4,3)=N(SUM(4,2)) = N(N(SUM(4,1))) = N(N(N(SUM(4,0)))) = N(N(N(4)))=N(N(5))=N(6)=7

Offensichtlich eine rekursive Funktion !

Als Methode in Java:

public int N(int x)

{ return x+1;}

public int SUM(int x, int y)

{

if(y==0) { return x;} else { return(N(SUM(x,y-1));}

}

Probieren sie diese rekursiven Funktionen in einem kleinen Applet aus.

Seite 24

primitiv - rekursive Funktionen

Hans-Georg Beckmann 2004

SUM (x,y) =x falls y=0

N(SUM(x,y-1)) sonst

Virtuelle Lehrerfortbildung imFach Informatik in Niedersachsen

Man kann schon ahnen, dass es wohl dann auch mglich sein muss, die Multiplikation zweier

ganzer positiver Zahlen auf die SUM-Funktion zurckzufhren.

Zuerst gilt es wieder eine Abbruchbedingung zu formulieren und dann die Multiplikation auf

eine wiederholte Addition zurchzufhren:

0 fr y=0

SUM(x, MUL(x,y-1)) sonst

Dabei entspricht die erste Zeile der Funktionsdefinition der Abbruchbedingung fr die

Rekursion.

Auch das wird zuerst an einem Beispiel genauer vorgerechnet:

MUL(3,3)= SUM(3,MUL(3,2)) = SUM(3,SUM(3,MUL(3,1))) = SUM(3,SUM(3,SUM(3,MUL(3,0)))) =

SUM(3,SUM(3,SUM(3,0))) = SUM(3,SUM(3,3)) = SUM(3,6)=9

Dabei htte man nun natrlich wieder die Summenfunktion rekursiv durch die Nachfolgerfunk-

tion berechnen lassen knnen.

Wir knnen also die Sammlung unserer Javamethoden um MUL erweitern:

public int MUL(int x, int y)

{

if(y==0){return 0;} else { return (SUM(x,MUL(x,y-1)));}

Man kann sich nun schon leicht vorstellen, wie der Stack bei einer Multiplikation durch diese

verschachtelten Rekursionen aussieht.

Probieren sie es an einigen Beispielen aus.

Aufgabe:

Formulieren sie eine Funktionsdefinition fr die Potenzierung POT(x,y) = xy, die auf die Funk-

tion MUL zurckgreift.

Seite 25

Nachfolger, Summe, Produkt

Hans-Georg Beckmann 2004

MUL (x,y) =

Virtuelle Lehrerfortbildung imFach Informatik in Niedersachsen

Aufgabe:

Die oben schon einmal definierte Fakulttsberechnung kann ebenfalls auf die hier angegebene

Art auf MUL zurckgefhrt werden. Fgen sie ihrem Applet eine entsprechende Methode hin-

zu.

Testen sie, wie weit das Javaprogramm fehlerfrei luft. Geht noch die Fakultt von 12 ?

Neben diesen primitiv-rekursiven Funktionen, die auch ein Beispiel fr indirekte Rekursion

sind , gibt es weitere Funktionen aus der Mathematik und aus der theoretischen Informatik, die

nicht primitiv - rekursiv sind.

Die Ackermannfunktion

Ein weiteres beliebtes Beispiel fr eine rekursive Funktion ist die Ackermannfunktion, die wie

folgt definiert ist:

y +1 falls x=0

Acker(x,y) = Acker(x-1,1) falls y=0

Acker(x-1,Acker(x,y-1)) sonst

Das sieht unfreundlich aus. Es ist eine Funktion mit zwei Parametern und anscheinend unter-

schiedlichen Abbruchbedingungen. Sie sieht auch nicht sehr "zugnglich" aus, da man auf den

ersten Blick nicht erkennt, wie sie sich verhalten wird. Knnten sie z.B. erahnen, was das Ergeb-

nis fr Acker (2,3) ist ?

Seite 26

Potenz und Fakultt

Hans-Georg Beckmann 2004

Virtuelle Lehrerfortbildung imFach Informatik in Niedersachsen

Wir arbeiten das per Hand ab !

Dazu werden wir einige Zwischenergebnisse brauchen, die wir uns bereitstellen:

Acker(1,0)=Acker(0,1)=2

Acker(1,1)=Acker(0,Acker(1,0))=Acker(0,2)=3

Acker(1,2)=Acker(0,Acker(1,1))=Acker(0,3)=4

Acker(2,0)=Acker(1,1)=3

Acker(1,3)=Acker(0,Acker(1,2))=Acker(0,4)=5

Acker(2,1)=Acker(1,Acker(2,0))=Acker(1,3)=Acker(0,Acker(1,2))=Acker(0,4)=5

Nun los :

Acker(2,3)=Acker(1,Acker(2,2)) =Acker(1,Acker(1,Acker(2,1))) =Acker(1,Acker(1,5))=Acker(1,Ak-

ker(0,Acker(1,4)))=Acker(1,Acker(0,Acker(0,Acker(1,3))))=Acker(1,Acker(0,Acker(0,5)))=Ak-

ker(1,Acker(0,6))=Acker(1,7)=Acker(0,Acker(1,6))=Acker(0,Acker(0,Acker(1,5)))=Acker(0,Ak-

ker(0,7))=Acker(0,Acker(0,7))Acker(0,8)=9

Wer wei, ob das wirklich stimmt. Hier muss offensichtlich ein Programm her, dass uns diese

Rechenarbeit abnimmt. ( Es soll brigens Lehrer geben, die als einzige Aufgabe fr eine mehr-

stndige Klausur Acker (8,12) zu Fu berechnen lassen)

Das Applet fr die Berechnung der Ackermannfunktion ist im Prinzip genauso aufgebaut, wie

das fr die Fakultt. In seiner