Rekursion

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Hallo miteinander,

ich bekunde etwas Mühe mit der rekursiven Berechnung der Mandelbrot-Menge.
Ich habe den folgenden Code geschrieben. Er ist (glaube ich) nicht schlecht, laut meinem Tutor könnte er aber "besser" sein. Meine Frage also: Wie würdet ihr diese rekursive Funktion schreiben?

Code: Alles auswählen

def mandelbrot(z, n_aktuell, c, n): 
    """ (complex, int, complex, int) -> int

    Berechnet die Folge z_{n+1} = z_n^2 + c startend bei z_{n_aktuell} = n. Beim ersten Aufruf der Funktion müssen z und n_aktuell 0 sein.
    Gibt die Anzahl Iterationen n zurück bis |z_n| <= 2 oder -1 falls keine Divergenz.
    """
    if n > 0:
        if (z.real*z.real + z.imag*z.imag) >= 4:
            return n_aktuell
        else:
            return mandelbrot(z*z+c, n_aktuell+1, c, n-1)
    else:
        return -1
Danke für jeden Hinweis.
Zuletzt geändert von MarcelF6 am Mittwoch 29. Oktober 2014, 14:26, insgesamt 1-mal geändert.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

MarcelF6 hat geschrieben:ich bekunde etwas Mühe mit der rekursiven Berechnung der Mandelbrot-Menge.
War das Teil der Aufgabe es rekursiv zu tun? Ansonsten würde ich keine Rekursion, sondern eine Schleife nehmen.

Hier sind ein paar schöne Numpy-Implementationen
http://wiki.scipy.org/Tentative_NumPy_T ... et_Example
http://nbviewer.ipython.org/gist/harris ... 0af9463c43 ("In [24]:" bis "In [29]:")
a fool with a tool is still a fool, www.magben.de, YouTube
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@MarcelF6: Wenn "nicht schlecht" heißt, dass der Code mit einem NameError aussteigt, :twisted: .
Wie MagBen schon anmerkte, würde man das in Python nicht rekursiv lösen.
Parameter, die beim externen Aufrufen bestimmte Werte haben, sollten diese sie per Default-Parameter bekommen.
Statt den Betrag selbst auszurechnen könnte man auch die abs-Funktion benutzen. Ansonsten kann man in 7 kurzen Zeilen Code nicht viel falsch machen.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Hallo miteinander,

die Aufgabe via for/while-loop zu lösen, war kein Problem.
Hier geht es aber explizit um Rekursion...

Danke für alle Hinweise.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Kosmetik: x**2 == x * x
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Code: Alles auswählen

def mandelbrot(z, c, n=0):
    return n if (z.real ** 2 + z.imag ** 2 >= 4) else \
        mandelbrot(z * z + c, c, n + 1)

if __name__ == '__main__':
    z = complex(0)
    for c in [complex(x / 10, y / 10) for x in range(10) for y in range(10)]:
        try:
            print('{} steps for c={}'.format(mandelbrot(z, c), c))
        except RuntimeError:
            print('too many steps for c={}'.format(c))
Bei der vorstehenden Lösung habe ich auf eine definierbare "harte" Grenze verzichtet und die verbliebenen if-else-Konstrukte in einen Ausdruck eingedampft. Die Grenze (das Rekursionslimit) wird von Python ohnehin vorgegeben.

Grüße ... bwbg
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn schon Einzeiler, dann mit allen Features:

Code: Alles auswählen

def mandelbrot(c, nmax=100, z=0, n=0):
    return -1 if n>nmax else n if abs(z) >= 2 else mandelbrot(c, nmax, z ** 2 + c, n + 1)
Antworten