SFZ FN Sj. 13/14

  • Published on
    02-Jan-2016

  • View
    20

  • Download
    1

DESCRIPTION

SFZ FN Sj. 13/14. Python 3 Rekursion. Rekursion. Prinzip der Rekursion: In einer Funktion wird die Funktion wieder aufgegriffen. Das darf allerdings nicht ohne Ende geschehen. - PowerPoint PPT Presentation

Transcript

  • SFZ FN Sj. 13/14Python 3 Rekursion

    GZG FN W.Seyboldt

  • RekursionPrinzip der Rekursion: In einer Funktion wird die Funktion wieder aufgegriffen. Das darf allerdings nicht ohne Ende geschehen.Wikipedia: Das Grundprinzip der Rekursion ist das Zurckfhren einer allgemeinen Aufgabe auf eine einfachere Aufgabe derselben Klasse. Das Grundprinzip der rekursiven Definition einer Funktion f ist: Der Funktionswert f(n+1) ergibt sich durch Verknpfung bereits berechneter Werte f(n), f(n-1), ... f(1) wird allerdings auf andere Art bestimmt.Beispiel: Berechne n! Vorgehen: n! = n* (n-1)!. Das heit, ich kann n! berechnen, wenn ich (n-1)! kenne. Es gilt 1!=1. fak01.py: Schreibe ein Programm mit der Methode fakrek(n), die n! rekursiv berechnet. Sie ruft fakrek(n-1) auf und multipliziert das Ergebnis von fakrek(n-1) mit n. Dieses Ergebnis wird dann zurckgegeben. Ist n==1: return 1. Bestimme die ersten 100 Glieder von der Folge (n!)

    GZG FN W.Seyboldt

  • RechenzeitRekursionen sind langsam und erfordern vom PC viel Aufwand. Wir wollen nun die Rechenzeit bestimmen, die man bentigt, um alle Fakultten rekursiv von 1 bis 500 zu bestimmen.Ergnze fak01 und speichere es als fak01a.py um die bentigten Befehle.

    from time import time startzeit = time() Rechnung endzeit = time()print "Bentigte Rechenzeit = %8.6f s" %(endzeit-startzeit)

    GZG FN W.Seyboldt

  • Iteration statt RekursionWie kann man die Probleme von rekursiven Methoden lsen?Oft kann man Rekursionen durch Schleifen ersetzenOder man wendet das Prinzip der Rekursion mit Generatoren an fak02.py: Schreibe ein Programm, das die Fakultt in Form einer Schleife berechnet Nenne die Methode fakiter(n) Das Programm soll die Methode weiterhin fakrek enthalten und die Rechenzeiten vergleichen.

    Ergebnis: Die Rechenzeiten unterscheiden sich recht wenig. Das ist nicht immer so. Auf der nchsten Folie schauen wir uns ein komplexeres Problem an.

    GZG FN W.Seyboldt

  • Fibonacci-Folge, fib01,pyDie Fibonacci-Folge: Die Fibonacci-Folge ist rekursiv definiert: fib(n)=fIb(n-1)+fib(n-2) und fib(1)=fib(2)=1.Die Fibonacci-Zahlen resultieren aus einem "knstlichen" Kaninchenproblem, das die folgenden Bedingungen erfllt: Die Anfangspopulation wird von einem Kaninchenpaar gebildet Ein neugeborenes Kaninchenpaar kann sich erst am Ende des ersten Monats paaren und wirft am Ende des zweiten Monates ein weiteres Paar. Ansonsten wirft jedes Kaninchenpaar jeweils ein weiteres Kaninchenpaar pro Monat. Sie sind unsterblich Aufgabe fib01.py : Schreibe eine Methode fibr1(), die die Fibonacci-Folge rekursiv berechnet. Bestimme die ersten 30 Glieder derFibonacci-Folge Bestimme die Rechenzeit.

    GZG FN W.Seyboldt

  • Probleme der RekursionWarum dauert das Programm so lange?Wenn man z.B. fib(6) berechnet, sieht der Aufrufbaum wie folgt aus: fib(2) wird also 5 mal aufgerufen. Wie lsst sich dies verbessern? Ein iterative Lsung findet sich nicht (so leicht).Was geht dann? Python bietet zwei Verfahren

    GZG FN W.Seyboldt

  • Verbesserung 1: fib02.pyJedes Mal wenn wir ein Folgenglied berechnet haben, speichern wir den Wert in einer Liste namens fibMem ab.Siehe fib02.py Aufgabe: Schreibe das Programm selbst Nenne die entsprechende Methode fibr2() Messe die Rechenzeit fr fibr2()Ergebnis: Wenn wir fibr1(35) aufrufen, bentigt das Programm knapp 9 s Wenn wir fibr2(999) aufrufen, erhalten wir die Antwort fast sofortAber Vorsicht: Auch bei dieser Variante, kann die Iterationstiefe berschritten werden.

    GZG FN W.Seyboldt

  • fibr2() - Vorschlag

    fibMem=[0,1,1] # fibr2(0)..fibr2(2)# Dies ist die globale Liste, die fib02 verwendet.

    def fibr2(n): # berprfe zuerst, ob fib(n) schon berechnet wurde if n

  • Generator (yield) Teil 1Python bietet noch ein Verfahren an, das noch geschickter ist, wenn es auch keinesfalls einfach zu verstehen ist. Ein Generator gen() ist eine Methode, die bei jedem Aufruf das nchste Element einer virtuellen Sequenz mit yield statt return zurckgibt, die sozusagen einen Wert der Folge nach dem anderen produziert bzw. abwirft (englisch: yield, abwerfen, einbringen). Gestartet wird mit g=gen() Jeder Aufruf des Generators mit g.next() ergibt das nchste Folgenelement.Definition einer Generatorsdefine fibo_generator():setze Startwerteloopberechne das nchste Folgenelementyield Folgenelementend loopAnwenden eines Generatorsfibo = fibo_generator()for n = 1 to 20: print fibo.next() Lies http://www.python-kurs.eu/generatoren.php Erstelle das dort beschriebene Programm, speichere es in generator01.py

    GZG FN W.Seyboldt

  • Generator (yield) Teil 2Der Generator kann dann in einer for-Schleife anstelle einer Liste verwendet werden. Aufgabe generator02.py : Erstelle einen Generator, der einfach die Quadratzahlen liefert. Nachdem der Generator mit next() einige Male aufgerufen wurde, soll ein neuer Generator erzeugt werden. Was beobachtest Du?Aufgabe fib03.py: Erstelle ein Python-Programm, das mit einem Generator die Fibonacci-Zahlen zurckgibt. Damit wird brigens kein berlauf mehr produziert, da kein (groer) Stack erzeugt wird.

    GZG FN W.Seyboldt

  • Lsungsvorschlag fib03.pydef fib3gen(): # Generator (enthlt yield()) a=1 b=1 while 1: yield a c=a+b a,b=b,c

    def fib3r(n): fibo=fib3gen() for i in range(n+1): z=fibo.next() return z # jetzt wird der Geneator beendet

    n=5000z= fib3r(n)print z

    GZG FN W.Seyboldt

  • Lsungsvorschlag fib04.pyDa beim Abarbeiten einer Liste, jedesmal das nchste Element erzeugt wird, kann statt der Liste auch die Methode stehen, die ein yield enthlt. Siehe http://www.python-kurs.eu/generatoren.php Generatoren und ihre Arbeitsweise

    def fib04gen(): a,b=1,1 while True: yield a a, b = b, a + bdef fib04(n): i=0 for z in fib04gen(): if i==n: return z i+=1

    GZG FN W.Seyboldt

  • Ein komplexer GeneratorLies http://www.python-kurs.eu/generatoren.php Rekursiver GeneratorErstelle perm01.py und teste den Code

    GZG FN W.Seyboldt

  • Pascalsches DreieckAufgabe: Schreibe ein Programm, das das Pascalsche Dreieck anzeigt:

    Die k. Zahl in der n. Zeile ist (n ber k oder k aus n)Jede Zahl ist die Summe der beiden ber ihr stehenden Zahlen. (Falls es keine zwei darber stehenden gibt ist die Zahl 1)Es gilt auch: ist die Anzahl der Mglichkeiten k aus n Kugeln auszuwhlen.Rekursiv: PascalschesDreieck01.pyGenerator: PascalschesDreieck02.py

    GZG FN W.Seyboldt

  • Die Kochsche Kurve: Kochkurve.pyWikipdeia: Die Koch-Kurve ist ein von dem schwedischen Mathematiker Helge von Koch 1904 vorgestelltes Beispiel fr eine berall stetige, aber nirgends differenzierbare Kurve. Man kann die Kurve anschaulich mittels eines iterativen Prozesses konstruieren: Ersetze das mittlere Drittel einer jeden Teilstrecke durch die Spitze eines gleichseitigen Dreiecks.

    GZG FN W.Seyboldt

  • Wdh. turtle (a_dummy.py)import turtle as tdef fkt(,,,s)return # Objekte erzeugen und initialisierenfenster = t.Screen()fenster.bgcolor('yellow')

    hugo = t.Turtle(shape="turtle")hugo.speed(9) # 0: am schnellsten, 10 schnell, 6 normal, 1 langsamhugo.color('blue')hugo.pensize(2)hugo.up()

    hugo.goto(0,0)hugo.down()fkt(,,,hugo) t.done() # Warten bis der Benutzer das Fenster schliet

    GZG FN W.Seyboldt

  • Aufgabe Kochkurve.pyZeichne mit der Turtle eine Kochkurve der Lnge 600 Pixel, wobei die geraden gezeichneten Stcke mindestens die Lnge ml haben sollen. Benutze dazu die Grundstruktur der letzten Folie.Rufe zeichneKoch(laenge, ml, s) rekursiv auf.Wenn laenge
  • Kochkurve.pydef zeichneKoch(laenge, ml, s): # laenge = gesamte Lnge der Kurve, # ml: Mindestlnge der geraden Teilstcke # s = turtle if laenge
  • Schneeflocke.pyZeichnet man ein gleichseitiges Dreieck und dann iterativ fr jede Seite die Kochsche Kurve, erhlt man eine Figur, die wie eine Schneeflocke aussieht.Die Lnge der Randkurve wird mit jeder Iteration immer lnger: Sie verlngert sich um den Faktor 4/3.Die Flche der Grenzkurve ist 1,6*Flche des gleichseitigen Dreiecks Bei jedem Iterationsschritt vergrert sich die Flche: Beim ersten Schritt um 3*(1/9); beim zweiten um 3*4*1/81, beim n-ten Schritt um Damit ist die Flchensumme

    GZG FN W.Seyboldt

  • Rekursives Programm lesenWas wird bei dem folgenden Beispiel gezeichnet?

    def dreieck(laenge, s): for i in range(3): s.forward(laenge), s.left(120)def DF(L, n): if n==0 or L

  • Baum01.pyMan nennt eine Figur selbsthnlich, wenn man innerhalb der Figur eine oder mehrere verkleinerte Kopien der ganzen Figur finden kann.

    GZG FN W.Seyboldt

  • SelbsthnlichkeitEine rekursive Zeichenprozedur ruft sich selbst im Anweisungsteil auf. Eine geometrische Figur heit selbsthnlich, wenn sie sich in kongruente Teile zerlegen lsst, die ihr alle hnlich sind. Vergrern wir eine der Teilfiguren, so ergibt sich das Ganze. Selbsthnliche Figuren lassen sich mit der Initiator-Generator-Methode erzeugen. Sie funktioniert wie folgt: In einem Streckenzug I, dem Initiator, wird jede Strecke durch eine Figur G, den Generator, ersetzt. Daraufhin wird jede (oder nur manche) Strecke der erzeugten Figur durch die Generatorfigur G ersetzt. Diese Streckenersetzung wird beliebig lange wiederholt. Aufgabe: Was ist der Generator bei der Kochkurve, was beim Baum.

    GZG FN W.Seyboldt

  • Rekursives Programm lesenif laenge
  • Baum0x.pyndere das Baumprogramm, mache den Baum realistischer.Baum02.py: Die Baumdicke ndernBaum04.py: Links und rechts soll der Baum variert werden.Baum06.py: Bringe den Zufall ins Spiel, d.h. die Baumdicke und Lnge soll sich zufllig ndern. Verwende: import random as ra ra.gauss(Mittelwert, Stdabweichung) ra.gauss(stuecklaenge, stuecklaenge*zuf) mit zuf etwa 0,3. stuecklaengeA=int(ra.gauss(stuecklaenge, stuecklaenge*zuf)) Wenn Dir das Zeichnen zu lange geht, verwende hugo.tracer(0) # sofort zeichnen

    GZG FN W.Seyboldt

  • Farn01Ein Farn ist recht simpel aufgebaut. Der Kern des Programms: def zeichneFarn(s, hoehe=200.): # Funktionsdefinition if hoehe >3: # falls Zeichenweg gro genug s.forward(hoehe) s.left(25) zeichneFarn(s, hoehe*0.5) # linker Teilbaum s.right(35) zeichneFarn(s, hoehe*0.7) # mittlerer Teilbaum s.right(25) zeichneFarn(s, hoehe*0.4) # rechter Teilbaum s.left(35) s.backward(hoehe) else: s.forward(hoehe) s.backward(hoehe)

    GZG FN W.Seyboldt

  • Pythagorasbaum.pyDer Initiator ist eine waagrechte Strecke. Der Generator: Ersetze die Strecke durch ein Quadrat mit einem rechtwinkligen Dreieck c:a:b=5:4:3 auf der Oberseite. Dabei werden die beiden Katheten des Dreiecks wieder durch den Generator ersetzt. Der Winkel bei der krzeren Seite ist

    GZG FN W.Seyboldt

  • DrachenkurveAttraktive rekursive Grafiken basieren oft auf dem Orientierungswechsel. Die Drachenkurve entsteht, wenn beim Generator abwechselnd der Haken nach links bzw. nach rechts ausgefhrt wird.

    GZG FN W.Seyboldt

  • Sierpinski-DreieckDas Sierpinksi-Dreieck entsteht dadurch, dass man von einem Dreieck iterativ das mittlere Viertel wegnimmt und dies bei den verbliebenden Dreiecken wiederholt.Siehe auch http://de.wikipedia.org/ wiki/Sierpinski-DreieckLese Doku\einfuehrung Rekursion.pdf S. 8

    GZG FN W.Seyboldt

  • Lsung Sierpinski def sierpinski(s, laenge, stufe, farbe): s.fillcolor(farbe) pos=s.position() s.left(60), s.forward(laenge), s.right(60) s.begin_fill() for i in range(0,3): s.forward(laenge) s.right(120) s.end_fill() if stufe>1: for i in range(0,3): sierpinski(s,laenge/2, stufe-1, farbe) s.forward(laenge), s.right(120) s.up(), s.goto(pos), s.down() return

    GZG FN W.Seyboldt

  • Trme von HanoiDas Spiel benutzt drei Stbe und eine Anzahl von Scheiben z.B. 9, die auf die Stbe gesteckt werden knnen. Anfnglich befinden sich alle Scheiben in absteigender Gre auf einem Stab angeordnet, d.h. die grte ist ganz unten und die kleinste ganz oben. Die Aufgabe besteht darin, diesen Turm von einem Stab auf einen anderen zu bewegen unter Beachtung der folgenden Regeln: In einem Zug darf immer nur eine Scheibe bewegt werden. Es kann immer nur die oberste Scheibe eines Stapels bewegt werden. Eine Scheibe kann auf einem anderen Stab nur abgelegt werden, wenn der Stab leer ist, oder wenn die Scheibe kleiner als die oberste Scheibe des Zielstapels ist. Lese http://www.python-kurs.eu/tuerme_von_hanoi.php und erstelle das zughrige Programm

    GZG FN W.Seyboldt

  • QuellenFraktale und Chaos (Mandelbrotmenge): Siehe http://mathematik.ph-weingarten.de/~hafenbrak/docs/chaos06/chaos01.pdf http://mathematik.ph-weingarten.de/~hafenbrak/docs/chaos06/chaos02.pdfhttp://mathematik.ph-weingarten.de/~hafenbrak/docs/chaos06/chaos03.pdfhttp://mathematik.ph-weingarten.de/~hafenbrak/docs/chaos06/chaos04.pdf http://mathestuff.de/rekursion_mit_python https://ddi.ifi.lmu.de/tdi/2013/upload/materialien-visualisierung-rekursiver-datenstrukturen/ Butterfly (Tkinter) http://www.pythonmania.de/article/pybutt.html Informatikunterlagen http://www.inf-schule.de/Selbsthnlihckeit, Zusf. Lese http://stubber.math-inf.uni-greifswald.de/~bandt/talks/gwd07.pdf

    GZG FN W.Seyboldt

    Siehe auch http://www.python-kurs.eu/rekursive_funktionen.php Lit http://www.mi.uni-koeln.de/c/mirror/f7alpha1.informatik.fh-muenchen.de/~schieder/programmieren-2-ss97/recursion.html Siehe https://www.fbi.h-da.de/fileadmin/personal/n.spangler/informatik_2/cpp_kap16.pdf Quelle http://en.literateprograms.org/Fibonacci_numbers_%28Python%29 Quelle http://openbook.galileocomputing.de/python/python_kapitel_13_004.htm Quelle http://www.python-kurs.eu/generatoren.php Quelle http://de.wikipedia.org/wiki/Koch-Kurve http://lakk.bildung.hessen.de/netzwerk/faecher/informatik/delphi/rekgraf/rekgraf7.htm.htmlhttp://lakk.bildung.hessen.de/netzwerk/faecher/informatik/delphi/rekgraf/rekgraf5.htm.htmlhttp://lakk.bildung.hessen.de/netzwerk/faecher/informatik/delphi/rekgraf/rekgraf7.htm.htmlhttp://mathestuff.de/rekursion_mit_python

Recommended

View more >