Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Rekursion vs. Iteration (https://www.delphipraxis.net/151976-rekursion-vs-iteration.html)

alzaimar 12. Jun 2010 15:40

AW: Rekursion vs. Iteration
 
Ich verstehe die kleinliche Rechthaberdiskussion nicht, bei der man die Integrität von Diskussionsteilnehmern in Frage stellt.

Mein Bauch sagt mir zwar, das man so ziemlich jedes Verfahren sowohl rekursiv als auch iterativ formulieren kann. Aber wenn nicht: WTF.

Ich bin und bleibe Anhänger der Rekursion und setze sie immer ein, wobei ich Tail-Recursion und hohe Verschachtelungstiefen vermeide. Natürlich schaue ich mir jede Lösung hinsichtlich ihres Big-Oh-Verhaltens kritisch an, und würde daher z.B. eine unsinnige Fibionacci-Implementierung, wie vom Gammatester süffisant vorgetragen, vermeiden.

Wenn ich mir die rekursiven Lösungen zum Türme-Von-Hanoi-Problem anschaue, oder die Ermittlung von Permutationen, oder eine Lösung des N-Damen-Problems, dann verstehe ich nicht, wie man iterative Lösungen per se bevorzugen kann.

Und wenn ich eine iterative Berechnung der Fakultät oder der Fibionacci-Folge sehe, verstehe ich auch nicht, wie man rekursive Lösungen per se bevorzugen kann. :-D

Delphi-Laie 12. Jun 2010 16:17

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von alzaimar (Beitrag 1028375)
eine unsinnige Fibionacci-Implementierung, wie vom Gammatester süffisant vorgetragen, vermeiden.

Warum unsinnig? Sie orientiert sich lediglich an der rekursiven mathematischen Definition und dürfte wohl all' das, was zugunsten der Rekursion hier ins Felde geführt wurde, wie Übersichtlichkeit und Einfachheit und womöglich einen mathematischen Exaktheitsbeweis im Nacken, in vollem Umfange aufweisen.

Zitat:

Zitat von alzaimar (Beitrag 1028375)
Und wenn ich eine iterative Berechnung der Fakultät oder der Fibionacci-Folge sehe, verstehe ich auch nicht, wie man rekursive Lösungen per se bevorzugen kann. :-D

Interessant ist - obwohl ich sie nicht gern zitiere - daß in der Wikipedia für die Endrekursion auch das Synonym „iterativ rekursiv“ benutzt wird. Sie scheint ein merkwürdiges Hybrid-/Übergangswesen zwischen der „klassischen“ / „echten“ Rekursion und der Iteration zu sein. Wer das eine will, muß das andere mögen. Rekursion (teilweise) abzuspecken, führt letztlich (teilweise) wieder zu der hier anscheinend von vielen verpönten Iteration. Doch taugt eine „Rekursion light“ keinesfalls als Nachweis dafür, daß sie vom Laufzeitverhalten her generell mit der Iteration mithalten kann.

Der - auch von mir nicht bezweifelte - tendenzielle Vorteil der Rekursion hinsichtlich Übersichtlichkeit und Wartbarkeit sehe ich bei solchen Quelltexten, die anscheinend die endrekursive Variante verkörpern, wie
Code:
private uint fib(uint n)
        {
            if (n == 0)
                return 0;
            else
                return fib(n, 1, 0);
        }

        private uint fib(uint n, uint x, uint y)
        {
            if (n == 1)
                return x;
            else
                return fib(n - 1, x + y, x);
        }
oder

Code:
function Fibonacci_Rekursiv2(Index : Integer) : Int64;
  function Fibonacci_Rekursiv_Help(f1,f2,n: Integer): Integer;
    begin
      if n = 0 then
        Result:=f1
      else
        Result:=Fibonacci_Rekursiv_Help(f2,f1+f2,n-1);
    end;
begin
  case Index of
    1, 2 : Result := 1;
    else Result := Fibonacci_Rekursiv_Help(0,1,Index);
  end;
end
leider nicht mehr gegeben: Da sich hier nicht an der rekursiven mathematischen Definition vollumfänglich orientiert wird, muß man sich in so etwas - egal, ob als ursprünglicher Programmierer oder später als Sichter des Quelltextes - auch erst einmal genau wie bei Iterationen hineindenken.

alzaimar 12. Jun 2010 16:58

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1028379)
Doch taugt eine „Rekursion light“ keinesfalls als Nachweis dafür, daß sie vom Laufzeitverhalten her generell mit der Iteration mithalten kann.

Deine Gedankengänge sind für mich nicht nachvollziehbar. Du stehst zudem in deinem Bestreben, Äpfel generell über Birnen zu stellen, ziemlich allein. Erstens gibt es Birnenliebhaber und zweites faule Äpfel. Das haut also nicht hin.

Die Tailrecursion ist Rekursion. Punkt. Sie sollte aber durch eine Schleife ersetzt werden, weil das einfach einfacher zu verstehen ist. Punkt. Das das nebenbei auch noch performanter ist, liegt an der Tatsache, das eine Schleife nun mal schneller ist. Hier ist naturgemäß eine Umformung in eine Iteration die richtige Wahl.

Eine andere Technik der Umformung (rekursiv => iterativ), Bookkeeping eines Stacks vs. rekursivem Aufruf und Stack ist dagegen nicht notwendigerweise performanter.

Ich habe vor einiger Zeit mal wieder ein iterstives mit einem rekursiven Quicksort verglichen: Da gibt es einfach keine relevanten Unterschiede mehr.

Wer allerdings einen Floodfill rekursiv implementiert, muss sich nicht wundern, wenn die Performance in den Keller geht.

Man muss einfach, wie bei allen Implementierungen, seinen gesunden Menschenverstand einsetzen, um die richtige Lösung zu finden. Dogmen á la "rekursiv ist eh zu langsam" sind hier nicht zielführend, übrigens genauso wenig wie "Eleganz ist alles".

Vor lauter Performancegeilheit darf man auch nicht vergessen, das es fast immer völlig egal ist, ob eine Anwendung 5 oder 5.02 Minuten benötigt. Viel wichtiger ist es mittlerweile, das der Code klar und lesbar ist. Lesbarer Code ist wartbar. Wartbarer Code ist zukunftssicher. Und zukunftssicherer Code sichert das Geschäft. So einfach ist das. Jedenfalls für mich.

Ich kann mit Aussagen, wie "Rekursion ist per se langsamer als Iteration" nichts anfangen. Denn es ist Quatsch.

Delphi-Laie 12. Jun 2010 17:13

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von alzaimar (Beitrag 1028385)
Ich kann mit Aussagen, wie "Rekursion ist per se langsamer als Iteration" nichts anfangen. Denn es ist Quatsch.

Natürlich. So pauschal eine solche Aussage ist, so falsch ist sie auch.

Mich würde in diesem Zusammenhang allerdings einmal interessieren, ob bei Problemlösungen, die sowohl iterativ als auch rekursiv möglich sind, es auch Fälle gibt, in denen die Rekursion hinsichtlich des Laufzeitverhaltens der Iteration substantiell (also vom Komplexitätsverhalten her) überlegen ist. Nachzuweisen, daß eine iterative einer (bestimmten) rekursiven Lösung überlegen ist, bedurfte es ja nur einer Folge, die schon seit dem späten Hochmittelalter (oder frühen Spätmittelalter) bekannt ist.

jfheins 12. Jun 2010 17:32

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1028387)
Mich würde in diesem Zusammenhang allerdings einmal interessieren, ob bei Problemlösungen, die sowohl iterativ als auch rekursiv möglich sind, es auch Fälle gibt, in denen die Rekursion hinsichtlich des Laufzeitverhaltens der Iteration substantiell (also vom Komplexitätsverhalten her) überlegen ist.

Ist unmöglich, da das Komplexitätsverhalten vom Algorithmus (also der Art der Problemlösung) und nicht von der Implementierung des Algorithmus (rekursiv/iterativ) abhängt. Du meinst schon das mit der Groß-O-Notation, oder? Denn ein rekursiver Quicksort und ein iterativer Quicksort haben beide eine Laufzeit von n*log(n) im Schnitt.

Zitat:

Nachzuweisen, daß eine iterative einer (bestimmten) rekursiven Lösung überlegen ist, bedurfte es ja nur einer Folge, die schon seit dem späten Hochmittelalter (oder frühen Spätmittelalter) bekannt ist.
Das "nachzuweisen" ist trivial.

Als Gegenbeispiel führe ich mal die Türme von Hanoi an: http://de.wikipedia.org/wiki/Türme_v...er_Algorithmus
Die rekursive Implementierung ist deutlich besser verständlich als die iterative. Beide haben natürlich das gleiche exponentielle Laufzeitverhalten.

Noch ein bereits genanntes Gegenbeispiel: Rekursiver Quicksort vs. iterativer Bubblesort. Sind ja beides Lösungen für das Sortierproblem - aber die rekursive Implementierung der Lösung ist deutlich schneller im Average Case ;)

Delphi-Laie 12. Jun 2010 17:57

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von jfheins (Beitrag 1028388)
Zitat:

Zitat von Delphi-Laie (Beitrag 1028387)
Mich würde in diesem Zusammenhang allerdings einmal interessieren, ob bei Problemlösungen, die sowohl iterativ als auch rekursiv möglich sind, es auch Fälle gibt, in denen die Rekursion hinsichtlich des Laufzeitverhaltens der Iteration substantiell (also vom Komplexitätsverhalten her) überlegen ist.

Ist unmöglich, da das Komplexitätsverhalten vom Algorithmus (also der Art der Problemlösung) und nicht von der Implementierung des Algorithmus (rekursiv/iterativ) abhängt. Du meinst schon das mit der Groß-O-Notation, oder?

Ja.

Zitat:

Zitat von jfheins (Beitrag 1028388)
Zitat:

Zitat von Delphi-Laie (Beitrag 1028387)
Nachzuweisen, daß eine iterative einer (bestimmten) rekursiven Lösung überlegen ist, bedurfte es ja nur einer Folge, die schon seit dem späten Hochmittelalter (oder frühen Spätmittelalter) bekannt ist.

Das "nachzuweisen" ist trivial.

Als Gegenbeispiel führe ich mal die Türme von Hanoi an: http://de.wikipedia.org/wiki/Türme_v...er_Algorithmus
Die rekursive Implementierung ist deutlich besser verständlich als die iterative. Beide haben natürlich das gleiche exponentielle Laufzeitverhalten.

Ich meinte doch ausdrücklich, ob es eine schnellere rekursive Lösung gibt. Die Verständlichkeit ist unberührt.

Zitat:

Zitat von jfheins (Beitrag 1028388)
Noch ein bereits genanntes Gegenbeispiel: Rekursiver Quicksort vs. iterativer Bubblesort. Sind ja beides Lösungen für das Sortierproblem - aber die rekursive Implementierung der Lösung ist deutlich schneller im Average Case ;)

Der Vergleich hinkt m.E. etwas. Es lassen sich zum einen auch rekursive (und auch iterative) Algorithmen finden, die langsamer als Bubblesort sind (Trippelsort, Slowsort), zum anderen gibt es auch iterative Sortieralgorithmen, die von der Geschwindigkeit her dem Quicksort wahrscheinlich mindestens ebenbürtig sind.

xZise 12. Jun 2010 18:05

AW: Rekursion vs. Iteration
 
Moin,
Zitat:

Zitat von Delphi-Laie (Beitrag 1028390)
[...]Der Vergleich hinkt m.E. etwas. Es lassen sich zum einen auch rekursive (und auch iterative) Algorithmen finden, die langsamer als Bubblesort sind (Trippelsort, Slowsort), zum anderen gibt es auch iterative Sortieralgorithmen, die von der Geschwindigkeit her dem Quicksort wahrscheinlich mindestens ebenbürtig sind.

Dann fass dich bitte selber an die Nase: Du kannst einen schlechten rekursiv implementierten Algorithmus für die Fibonacci-Folge nicht mit einen optimierten iterativen Algorithmus vergleichen.

Das
Delphi-Quellcode:
fib(n) := fib(n - 1) + fib(n - 2)
nicht das beste Laufzeitverhalten hat, das hast du ja demonstriert, aber es gibt rekursive Implementierungen die sind so gut wie die iterativen. Ob das nun die ursprüngliche mathematische Definition ist, ist doch irrelevant, ob die rekursive Implementierung gut ist.

Und warum muss der rekursive Algorithmus unbedingt schneller sein? Solange sie gleich schnell sind passt das doch? Weil dann ist eine rekursive Implementierung meistens besser lesbar.

MfG
Fabian

jfheins 12. Jun 2010 18:12

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1028390)
Ich meinte doch ausdrücklich, ob es eine schnellere rekursive Lösung gibt. Die Verständlichkeit ist unberührt.

Wir drehen uns im Kreis :mrgreen:

Bei Fibonacci habe ich dir eine rekursive Implementierung mit gleicher Komplexität gezeigt, die du wegen der verringerten Verständlichkeit (zu recht) abgelehnt hast. (Fibonacci ist eben ein Problem, dass man am besten per iteration löst)
Bei den Türmen von Hanoi habe ich dir gezeigt, dass rekursive Implementierungen bei gleicher Komplexität übersichtlicher sein können. Und du bestehst auf einer schnelleren Lösung ... schon die Entwicklung der iterativen Lösung die du jetzt nur auf Wikipedia angeguckt hast, hat wahrscheinlich Tage wenn nicht gar Wochen gebraucht, während die rekursive Variante schnell hingeschrieben ist.

mkinzler 12. Jun 2010 19:06

AW: Rekursion vs. Iteration
 
Zitat:

Wir drehen uns im Kreis
Wir sind sozusagen Derwische

Mithrandir 12. Jun 2010 20:01

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von jfheins (Beitrag 1028394)
Wir drehen uns im Kreis :mrgreen:

Das hab ich euch schon vor 15 Beiträgen versucht klar zu machen... :wall:

JasonDX 13. Jun 2010 01:22

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1028387)
Mich würde in diesem Zusammenhang allerdings einmal interessieren, ob bei Problemlösungen, die sowohl iterativ als auch rekursiv möglich sind, es auch Fälle gibt, in denen die Rekursion hinsichtlich des Laufzeitverhaltens der Iteration substantiell (also vom Komplexitätsverhalten her) überlegen ist.

Ich tendiere zu nein. Sollte ich die Zeit dafür finden, ließe sich evt. ein Beweis für die Äquivalenz beider Verfahren finden.

Zitat:

Zitat von Delphi-Laie (Beitrag 1028387)
Nachzuweisen, daß eine iterative einer (bestimmten) rekursiven Lösung überlegen ist, bedurfte es ja nur einer Folge, die schon seit dem späten Hochmittelalter (oder frühen Spätmittelalter) bekannt ist.

Ein klares Zeichen, dass du Beiträge entweder nicht liest oder nicht verstehst. Es ist bereits gezeigt worden, dass die iterative Lösung der rekursiven nicht überlegen ist. Tailrecursion is recursion! Bitte lese zukünftig Beiträge, bevor du ihnen widersprichst.

greetz
Mike

negaH 13. Jun 2010 13:10

AW: Rekursion vs. Iteration
 
@Alzaimar
Zitat:

Das das nebenbei auch noch performanter ist, liegt an der Tatsache, das eine Schleife nun mal schneller ist
Das ist eben nicht richtig. Deine Aussage bezieht sich nur auf eine spezifische Hardware auf der dann Schleifen schneller laufen als zb. die gleiche Anzahl von Sprüngen zu Unterfunktionen.

Das gilt zb. für die Hardware FPGA oder Papier eben nicht mehr. Dort existiert kein Overhead im Speicher und Performance beim Aufruf von Unterfunktionen weil sie durch die Synthese eliminiert werden oder einfach nicht vorhanden sind.

Letzendlich sind es auch nicht "iterative" und/oder "rekursive" Verfahren. Sondern es ist ein und das selbe Verfahren das man schriftlich entweder iterativ oder rekursiv niederschreibt. Was am Ende in Hardware ankommt ist eine Frage der Compiler/Synthese und der Hardware selber.

Betrachtet man also die Frage "rekursiv vs. iterativ" unabhängig von Hardware dann sind sie identisch in ihrer Komplexität, Big O. Bezieht man die Hardware und Compiler etc.pp. mit in die Fragestellung ein dann muß man auch diese als Faktor berücksichtigen. Und erst da wird man dann leichte Nachteile der Rekursion gegenüber der Iteration haben wenn es sich zb. um ASICs handelt aber eben nicht bei FPGAs/CPLDs oder Quantenrechnern.

Dieser Overhead auf ASICs entsteht ausschließlich durch folgende Faktoren:
- zusätzliche CPU Takte sind nötig bei Sprüngen
- zusätzlicher Stack ist nötig zum Speichern der Rücksprungadresse und Einrichten des Stackframes der rekursiven Unterfunktion
- zusätzliche CPU Takte sind nötig für diese Stackeinrichtung und Stackbereinigung
- ein RET zum Aufrufer ist nötig

Das sind alles nur Faktoren auf Grund der CPU Architektur die eben Sprünge benachteiligt zu Programmcode der ohne diese auskommt wie bei iterativen Umsetzungen.

Als letztes kommt noch der Punkt hinzu das zb. der Delphi Compiler nicht über Funktionsrümpfe hinweg optimieren kann. Er wird also besser eine iterative Funktion optimieren können als deren rekursve Schreibweise.

Das alles sind aber Punkte die man bei der generellen Bewertung "iterativ vs. rekursiv" aussen vor lassen muß. Und dann ergibt sich wieder das gewohnte mathematische Bild das beide äquvivalente Schreibweisen der selben Sache sind und nichts mehr.

Wenn dem so ist wird nun auch logsich das man sich bei dieser Frage nur auf die Fragestellung: was ist verständlicher beziehen darf. Und das hängt letzendlich vom Algorithmus und der Zielsetzung ab. Bei bestimmten, wenigen Problemen ist die iterative Schreibweise einfacher zu verstehen, bei den meisten Problemen wird aber schon bei der Mathematik und deren Formel die rekusive Schreibweise bevorzugt da sie intuitiver und einfacher ist. Vernachlässigt man also mal den mariginalen Performance/Speicheroverhead der auf ASICs systembedingt einen Unterschied ausmacht dann ist in den meisten Fällen die rekursive Schreibweise die bessere Wahl. Nicht weil sie schneller sein könnte oder weniger Speicher verbraucht, das haben wir ja nun hinlänglich ausdiskutiert das dies nicht der Fall sein kann und darf, sondern weil sie angemessener ist und verständlicher.

Gruß Hagen

negaH 13. Jun 2010 13:19

AW: Rekursion vs. Iteration
 
Zitat:

Das gilt zb. für die Hardware FPGA oder Papier eben nicht mehr. Dort existiert kein Overhead im Speicher und Performance beim Aufruf von Unterfunktionen weil sie durch die Synthese eliminiert werden oder einfach nicht vorhanden sind.
Betrachtet man mal die Harwdare Papier genauer in diesem Rahmen dann sind rekursive Scheibweisen sogar Speicher=Papier schonender als die meisten iterativen Schreibweisen. In diesem Fall kann man unter Berücksichtung "Harwdare ist Papier" sogar behaupten das rekursive Schreibweisen besser sind als iterative. Auch die Resource "Performance" ist in diesem Fall besser da man weniger Formeln eben schneller schreiben kann als mehr Formeln.

Gruß Hagen

Delphi-Laie 13. Jun 2010 14:45

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von JasonDX (Beitrag 1028441)
Zitat:

Zitat von Delphi-Laie (Beitrag 1028387)
Nachzuweisen, daß eine iterative einer (bestimmten) rekursiven Lösung überlegen ist, bedurfte es ja nur einer Folge, die schon seit dem späten Hochmittelalter (oder frühen Spätmittelalter) bekannt ist.

Ein klares Zeichen, dass du Beiträge entweder nicht liest oder nicht verstehst. Es ist bereits gezeigt worden, dass die iterative Lösung der rekursiven nicht überlegen ist. Tailrecursion is recursion! Bitte lese zukünftig Beiträge, bevor du ihnen widersprichst.

Zunächst einmal heißt es „lies“ (oder heißt die inzwischen aus der Mode gekommen Dateibezeichnung „lesemich.txt“?). Auch sollte ein Forumsverantwortlicher sich mit solchen indiskutablen Aussagen besser zurückhalten. Für diesen Umgangston seitens des Forumsstabes gibt es nämlich schon ein anderes Delphi-Forum. Ich verstand zudem sehr wohl, daß man Iterationen auch über Rekursion (bzw. umgekehrt) abbilden kann, daß es da eine Äquivalenz gibt.

Ich dachte eigentlich, daß ich mich klar genug ausdrückte: Einer bestimmten rekursiven Lösung. Es gibt auch eine andere, für die das nicht gilt.

Ich werde Dir mal ein Gleichnis, das mit Programmierung nun überhaupt nichts zu tun hat, offenbaren: In meiner Schulklasse stritt sich mal ein Schüler mit einer Lehrerin, ob man ein Pflänzlein nur in einen größeren Blumentopf umpflanzt oder ob es auch in einen der gleichen Größe möglich bzw. sinnvoll ist. Die Lehrerin meinte, ein größerer sei nicht zwangsläufig, der Schüler schon. Schon damals spürte ich und auch heute bin ich noch der Meinung, daß jeder auf seine Weise recht hatte. Und so etwa kommt mir das mit den iterativen Rekursionen wenigstens bei dem hier so strapazierten Beispiel der Fibonacci-Berechnung auch vor: Natürlich kann man auch eine Rekursion dort hineinwürgen, wenn man denn unbedingt eine haben möchte, weil man sie so sehr mag, aber die eingangs so hochgelobten Vorteile wie Übersichtlichkeit, Wartbarkeit, geringeres Fehlerrisiko usw. bleiben dabei nach meiner Einschätzung voll auf der Strecke, sie sind jedenfalls nicht offensichtlich besser als bei der Iteration. Dafür stimmt aber das Laufzeitverhalten. Beides ist anscheinend wenigstens an diesem Beispiel nicht unter einen Hut zu bringen (weshalb ich die Pauschalität weiterhin negiere). Welchen Vorteil nun eine solche Rekursion gegenüber der Iteration hat, weiß ich immer noch nicht, aber ich möchte es nunmehr auch nicht mehr wissen.

jfheins 13. Jun 2010 15:05

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1028524)
Ich verstand zudem sehr wohl, daß man Iterationen auch über Rekursion (bzw. umgekehrt) abbilden kann, daß es da eine Äquivalenz gibt.

Das ist schön, das habe ich nämlich immer wieder bezweifelt.


Zitat:

Zitat von Delphi-Laie (Beitrag 1028524)
Natürlich kann man auch eine Rekursion dort hineinwürgen, wenn man denn unbedingt eine haben möchte, weil man sie so sehr mag, aber die eingangs so hochgelobten Vorteile wie Übersichtlichkeit, Wartbarkeit, geringeres Fehlerrisiko usw. bleiben dabei nach meiner Einschätzung voll auf der Strecke, sie sind jedenfalls nicht offensichtlich besser als bei der Iteration.Dafür stimmt aber das Laufzeitverhalten. Beides ist anscheinend wenigstens an diesem Beispiel nicht unter einen Hut zu bringen

Richtig. Das liegt daran, dass sich für Fibonacci die iterative Problemlösung besser eignet. Das heißt aber nicht dass Iteration allgemein und immer besser ist, sondern bei diesem Problem. Ich hatte das Gefühl, du verallgemeinerst das Beispiel. Siehe auch:
Zitat:

Zitat von alzaimar (Beitrag 1028375)
Wenn ich mir die rekursiven Lösungen zum Türme-Von-Hanoi-Problem anschaue, oder die Ermittlung von Permutationen, oder eine Lösung des N-Damen-Problems, dann verstehe ich nicht, wie man iterative Lösungen per se bevorzugen kann. Und wenn ich eine iterative Berechnung der Fakultät oder der Fibionacci-Folge sehe, verstehe ich auch nicht, wie man rekursive Lösungen per se bevorzugen kann. :-D

Zitat:

(weshalb ich die Pauschalität weiterhin negiere).
Was negierst du? Du hast doch oben selbst gesagt, dass du verstanden hast dass man immer Rekursion auf Iteration abbilden kann und umgekehrt. Also eine 100% Äquivalenz was die Laufzeitkomplexität angeht.
Zitat:

Welchen Vorteil nun eine solche Rekursion gegenüber der Iteration hat, weiß ich immer noch nicht, aber ich möchte es nunmehr auch nicht mehr wissen.
Bei manchen Problemen (Fibonacci gehört nicht dazu) ist die rekursive Schreibweise leichter verständlich und übersichtlicher als die iterative. (Gleicher Algorithmus und damit gleiche Komplexität wohlgemerkt) Reicht das nicht?

mkinzler 13. Jun 2010 15:06

AW: Rekursion vs. Iteration
 
Da bist du nunmal anderer Meinung wie wir. Wenn hier einer eine Behauptung aufstellt ohe diese wirklich zu belegen, andere Antworten ignoriert, andere diskussionsteilnehmer beleidigt, dann ist es durchaus unsere Aufgabe ihn darauf hinzuweisen!

JasonDX 13. Jun 2010 15:41

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1028524)
Zunächst einmal heißt es „lies“ (oder heißt die inzwischen aus der Mode gekommen Dateibezeichnung „lesemich.txt“?).

Es ist nunmal nicht jeder Deutscher in diesem Forum. Mir wärs eh lieber, wenn die ganze Diskussion auf englisch geführt werden würde. Aber danke für den Hinweis...

Zitat:

Zitat von Delphi-Laie (Beitrag 1028524)
Ich verstand zudem sehr wohl, daß man Iterationen auch über Rekursion (bzw. umgekehrt) abbilden kann, daß es da eine Äquivalenz gibt.

Ich dachte eigentlich, daß ich mich klar genug ausdrückte: Einer bestimmten rekursiven Lösung. Es gibt auch eine andere, für die das nicht gilt.

Du hast dich offensichtlich nicht klar genug ausgedrückt. Folgendes Zitat lässt auch relativ wenig Interpretationsmöglichkeiten offen:
Zitat:

Zitat von Delphi-Laie (Beitrag 1028387)
Nachzuweisen, daß eine iterative einer (bestimmten) rekursiven Lösung überlegen ist, bedurfte es ja nur einer Folge, die schon seit dem späten Hochmittelalter (oder frühen Spätmittelalter) bekannt ist.

Entweder du hast eine triviale Aussage getroffen (bspw. Quicksort rekursiv ist besser als Bogosort iterativ), woraus sich aber keine sinnvollen Schlüsse ziehen lassen können, und schon gar nicht für die Diskussion relevant sind, oder du sprichst hier eindeutig von der pauschalen Überlegenheit der iterativen Implementierung der Fibonaccifolge über der rekursiven. Kannst du diese dann begründen? Ich behaupte, die Endrekursive Variante ist mindestens so einfach zu erkennen wie die iterative, gleich schnell, dafür aber einfacher zu zeigen. Bis auf die Lesbarkeit, welche ein subjektiver Faktor ist, gibt es keine Begründung, warum die iterative Implementierung der rekursiven Überlegen sein soll. Ein objektiver Vorteil der rekursiven Variante ist die Trivialität, ihre Korrektheit zu zeigen. Lässt man subjektives Empfinden beiseite, wäre also die rekursive Variante tatsächlich der iterativen überlegen.

Zitat:

Zitat von Delphi-Laie (Beitrag 1028524)
Und so etwa kommt mir das mit den iterativen Rekursionen wenigstens bei dem hier so strapazierten Beispiel der Fibonacci-Berechnung auch vor: Natürlich kann man auch eine Rekursion dort hineinwürgen, wenn man denn unbedingt eine haben möchte, weil man sie so sehr mag, aber die eingangs so hochgelobten Vorteile wie Übersichtlichkeit, Wartbarkeit, geringeres Fehlerrisiko usw. bleiben dabei nach meiner Einschätzung voll auf der Strecke, sie sind jedenfalls nicht offensichtlich besser als bei der Iteration.

  • Übersichtlichkeit: Das ist ein subjektives Empfinden. Es gibt Leute, die kommen mit 12 verschachtelten Schleifen besser klar als mit einer Rekursion, und es gibt Leute, bei denen es umgekehrt ist.
    Für mich ist die endrekursive Variante immernoch lesbarer als die iterative Schleife. Aber das ist wie gesagt Gewöhnungssache.
  • Wartbarkeit: Einen 4zeiler, bei dem 1 Vergleich vorkommt, ist definitiv einfacher zu warten als eine Schleife, bei der sonstwelche Variablen rumgetauscht werden.
  • geringeres Fehlerrisiko: Dieses ist bei der Rekursiven Variante immer gegeben. Rekursive Funktionen können sehr einfach bewiesen werden - Auch umformungen auf Endrekursion ect. Somit kann man auf Papier den rekursiven Ausdruck beweisen und 1:1 ins Programm übernehmen. Dies bietet definitiv weniger Fehlerpotential als eine iterative Schleife, da diese nicht so direkt von einem bewiesenermaßen korrekten Term in ein Programm überführt werden kann.
Die meisten Vorteile sind also immernoch gegeben, und die restlichen bleiben höchstens auf der Strecke des subjektiven Empfindens.

greetz
Mike

Sharky 13. Jun 2010 17:22

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1028524)
Zitat:

Zitat von JasonDX (Beitrag 1028441)
... Bitte lese zukünftig Beiträge, bevor du ihnen widersprichst.

Zunächst einmal heißt es „lies“ (oder heißt die inzwischen aus der Mode gekommen Dateibezeichnung „lesemich.txt“?). Auch sollte ein Forumsverantwortlicher sich mit solchen indiskutablen Aussagen besser zurückhalten. Für diesen Umgangston seitens des Forumsstabes gibt es nämlich schon ein anderes Delphi-Forum. ....

STOP
Hier wurde wohl nicht als "Forenverantwortlicher" gesprochen. Auch ist eine Diskussion über die richtige Schreibweise absolut unnötig. Deine Versuche jemandem ein schlechtes Verhalten im Forum unterzuschieben wurden schon bemerkt. Glube mir; es funktioniert hier ganz sicher nicht!

Wenn hier nur noch persönlich Anfeindungen vorgetragen werden werden wir im Team beraten und dann denn Thread schliessen.

P.S.: aus der englischen Word readme auf das richtige deutsche Wort zu schliessen zeigt sehr schön wie in diesem Thread argumentiert wird :roll:

Delphi-Laie 15. Jun 2010 19:41

AW: Rekursion vs. Iteration
 
Markus Kinzler....

Zitat:

Zitat von mkinzler (Beitrag 1028530)
Da bist du nunmal anderer Meinung wie wir. Wenn hier einer eine Behauptung aufstellt ohe diese wirklich zu belegen, andere Antworten ignoriert, andere diskussionsteilnehmer beleidigt, dann ist es durchaus unsere Aufgabe ihn darauf hinzuweisen!

So etwas weise ich zurück, und zwar deshalb, weil Du - obwohl Moderator - m.E. nicht neutral bist. Wo warst Du, als mich jemand absichtlich (?) und öffentlich in dieser Diskussion zu meinem Ungunsten fehlinterpretierte, was ich zudem leicht widerlegen konnte, und damit emotionale Spannung erzeugte?


Zurück zum Thema. Ich ließ mir absichtlich ein wenig Zeit für eine erneute Antwort. In dieser Diskussion wurde m.E. teilweise sogar erheblich aneinander vorbeigeredet. Richtig ist, rein formal und von der Definition her, daß Rekursion dadurch charakterisiert ist, daß sich Programmteile (immer Unterprogramme?) (ggf. wiederholt) selbst aufrufen. Rekursion und Iteration kann man in bestimmter Weise aufeinander abbilden (es gibt sozusagen eine Schnittmenge). Die folgliche Kongruenz, ja fast schon Äquivalenz von Rekursion und Iteration führe ich zu folgendem absurden Höhepunkt:

Delphi-Quellcode:
procedure rekursion;
begin
rekursion
end
versus
Delphi-Quellcode:
repeat
until false
Gibt es einen substantiellen Unterschied zwischen beiden Programmteilen, insbesondere hinsichtlich ihres Laufverhaltens? Anscheinend nein, denn beides sind Endlosschleifen (abgesehen davon, daß erstere den Stack schnell überlaufen läßt). Zudem ruft süffisanterweise sich im 2. Codeschnipsel auch die Schleife selbst immer wieder auf, es ist also auch sich selbst (immer wieder) aufrufender Code!

Ist es also das, was der Originalposter wohl gemeint haben mag, als er Rekursion und Iteration gegeneinander antreten ließ? Ganz sicher und offensichtlich nicht, denn damit wäre eine solche Gegenüberstellung überflüssig.

Was ich in dieser Diskussion bisher von keinem Diskussionteilnehmer las, werfe ich jetzt deshalb hier ein: Rekursion ist eine selbstähnliche Struktur, und weil wir im Bereich der Informatik sind, eine selbstähnliche Algorithmen-/Programmablaufstruktur (das ist nicht identisch)!

Das Wesen der Selbstähnlichkeit besteht darin, daß sich etwas selbst in gleicher oder wenigstens ähnlicher Gestalt selbst enthält. Nicht notwendig ist, daß die Teile erster Subordnung mehrmals vorhanden sind. Doch die Selbstähnlichkeit entfaltet erst ihre volle Pracht, ihr volles Wesen, wenn das gegeben oder zumindest möglich ist. Deshalb folgende Unterscheidungen:

1. Jedes Element enthält sein eigenes Abbild in der jeweils 1. Subebene nur einmal. So etwas ist z.B. bei der rekursiven Fakultät oder - im materiellen Bereich - bei den russischen Puppen namens Matrjoschka der Fall. Ich bleibe dabei, daß eine solche Rekursion nur eine „Lightversion“ ist, da sie letztlich mit der Iteration konformläuft.

2. Die Anzahl der Elemente (=Subprozesse) kann größer als 1 sein, so z.B. in Bäumen (und so auch in hierarchischen Dateisystemen).

3. Die Anzahl der Elemente (=Subprozesse) ist sicher größer als 1, so z.B. bei der rekursiven Fibonacciglied(er)berechnung.

Erst in den Fällen 2 und 3 entfaltet die Rekursion ihr wahres Wesen: Sie ist elegant zu beschreiben (bzw. ist eine elgante Methode, Probleme zu lösen bzw. Problemlösungen darzustellen) und zu implementieren und führt zu kurzen, sicher auch gut wartbaren Quelltexten. Das Laufzeitverhalten ist dagegen eher mau, denn diese Baumstruktur des Prorgrammablaufes beim Aufrufen der rekursiv aufgerufenen Unterprogramme x. Ordnung führen mit ziemlicher Sicherheit zu mindestens exponentiellem Laufzeitverhalten (bei der Fakultät z.B. sogar zu hyperexponentiellem Wachstum). Wollte man solche rekursiven Algorithem in adäquate iterative transformieren, so ist das entweder unmöglich (?), sehr aufwendig (wie es hier jemand bezüglich Fibonacci andeutete) oder nur unbefriedigend (s. Quicksort, falls R. Sedgewicks Aussage immer noch aktuell ist) möglich.

Ich hoffe, daß ich das Eingangsthema nunmehr wieder so aufgriff, wie es vermutlich (?) gemeint war/ist, und auch, daß mein Standpunkt nunmehr nachvollziehbarer ist.

Daniel 15. Jun 2010 20:12

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1029121)
Zudem ruft süffisanterweise sich im 2. Codeschnipsel auch die Schleife selbst immer wieder auf, es ist also auch sich selbst (immer wieder) aufrufender Code!

Und genau das halte ich für unpräzise. Die Schleife (nun nicht gerade Dein Beispiel, aber allgemeine Schleifen) enthalten Code, der wiederholt ausgeführt wird. Du hast ja völlig korrekt angemerkt, dass im ersten Beispiel der Stack zum Problem wird und das ist der substantielle technische Unterschied zwischen beiden Varianten. In der zweiten Variante springt der Programmzeiger zum Anfang der Schleife, der Kontext bleibt gleich. In der ersten Variante, der Rekursion, wird eine frische, neue Funktion mit ihren eigenen frisch initialisierten lokalen Variablen aufgerufen. Es mag sein, dass am Ende beide Fassungen zum gleichen Rechenergebnis kommen, aber das Verhalten zur Laufzeit ist für meine Begriffe gänzlich unterschiedlich.

Zitat:

Zitat von Delphi-Laie (Beitrag 1029121)
Das Laufzeitverhalten ist dagegen eher mau, denn diese Baumstruktur des Prorgrammablaufes beim Aufrufen der rekursiv aufgerufenen Unterprogramme x. Ordnung führen mit ziemlicher Sicherheit zu mindestens exponentiellem Laufzeitverhalten (bei der Fakultät z.B. sogar zu hyperexponentiellem Wachstum).

Und warum das Laufzeitverhalten per se mau sei, kann ich aus Deinem Beitrag immer noch nicht entnehmen. Kannst Du die Formulierung "exponentielles Verhalten" präzisieren? Ich kenne z.B. exponentielles Wachstum - aber nicht exponentielles Verhalten.

Delphi-Laie 15. Jun 2010 20:23

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von Daniel (Beitrag 1029126)
Zitat:

Zitat von Delphi-Laie (Beitrag 1029121)
Das Laufzeitverhalten ist dagegen eher mau, denn diese Baumstruktur des Prorgrammablaufes beim Aufrufen der rekursiv aufgerufenen Unterprogramme x. Ordnung führen mit ziemlicher Sicherheit zu mindestens exponentiellem Laufzeitverhalten (bei der Fakultät z.B. sogar zu hyperexponentiellem Wachstum).

Und warum das Laufzeitverhalten per se mau sei, kann ich aus Deinem Beitrag immer noch nicht entnehmen. Kannst Du die Formulierung "exponentielles Verhalten" präzisieren? Ich kenne z.B. exponentielles Wachstum - aber nicht exponentielles Verhalten.

Laufzeitverhalten schrieb ich.

Dann gehe mal einen rekursiven Algorithmus (im engeren Sinne, wie ich es ausführlich beschrieb), während er abläuft (also den Prozeß seines Ablaufes) durch: Die hierarchieniedrigsten Aufrufe sind die häufigsten! Konkret z.B. beim rekursiven Fibonacci: Fib(0) bzw. Fib(1) werden am häufigsten berechnet. Ziseliert man diesen Prozeß (graphisch), entsteht eine Baumstruktur. Und die Anzahl der Elemente von Bäumen ist - soweit ich weiß - exponentiell.

Edit: So allgemein gilt das doch nicht. Beim Quicksort ist das Laufzeitverhalten viel günstiger (logarithmisch), allerdings gibt es dort keine Mehrfachaufrufe: Was sortiert ist, wird nie wieder vom Algorithmus berührt (vielleicht ist das schon der Grund für die gute Komplexität?!), im Gegensatz zu den vielen Mehrfachberechnungen bei z.B. dem rekursiven Fibonacci. Das mehrmalige (konkret immer zweifache) Aufrufen von hierarchiegleichen Subprozessen (wie im Vorbeitrag ausgeführt) ist aber auch hier gegeben.

JasonDX 15. Jun 2010 22:26

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1029121)
Zurück zum Thema. Ich ließ mir absichtlich ein wenig Zeit für eine erneute Antwort. In dieser Diskussion wurde m.E. teilweise sogar erheblich aneinander vorbeigeredet. Richtig ist, rein formal und von der Definition her, daß Rekursion dadurch charakterisiert ist, daß sich Programmteile (immer Unterprogramme?) (ggf. wiederholt) selbst aufrufen. Rekursion und Iteration kann man in bestimmter Weise aufeinander abbilden (es gibt sozusagen eine Schnittmenge).

Diese Schnittmenge ist die Menge der derzeit berechenbaren Sprachen.

Zitat:

Zitat von Delphi-Laie (Beitrag 1029121)
Die folgliche Kongruenz, ja fast schon Äquivalenz von Rekursion und Iteration führe ich zu folgendem absurden Höhepunkt:

Delphi-Quellcode:
procedure rekursion;
begin
rekursion
end
versus
Delphi-Quellcode:
repeat
until false
Gibt es einen substantiellen Unterschied zwischen beiden Programmteilen, insbesondere hinsichtlich ihres Laufverhaltens? Anscheinend nein, denn beides sind Endlosschleifen (abgesehen davon, daß erstere den Stack schnell überlaufen läßt).

Das Laufzeitverhalten eines Algorithmus ist nicht von der Art seiner Implementierung abhängig. Man kann relativ einfach aus einem iterativen Programm ein Rekursives erstellen, und umgekehrt. Mit selbem Laufzeitverhalten. Wenn du möchtest, kann ich dir zumindest die Idee dahinter erklären, auch wenns dann etwas theoretisch werden könnte.

Zitat:

Zitat von Delphi-Laie (Beitrag 1029121)
1. Jedes Element enthält sein eigenes Abbild in der jeweils 1. Subebene nur einmal. So etwas ist z.B. bei der rekursiven Fakultät oder - im materiellen Bereich - bei den russischen Puppen namens Matrjoschka der Fall. Ich bleibe dabei, daß eine solche Rekursion nur eine „Lightversion“ ist, da sie letztlich mit der Iteration konformläuft.

Was genau meinst du mit "konformlaufen"? Dass sich die Rekursion auf einen iterativen Ablauf zurückführen lässt? Dann ist jede Rekursion eine "Lightversion".

Zitat:

Zitat von Delphi-Laie (Beitrag 1029121)
3. Die Anzahl der Elemente (=Subprozesse) ist sicher größer als 1, so z.B. bei der rekursiven Fibonacciglied(er)berechnung.

Das hängt ganz von der Berechnungsmethode ab. Nimmt man die triviale Implementierung, so ist die Anzahl der direkten Unteraufrufe entweder 0 oder 2. Überträgt man diese Berechnung in eine iterative Form (ohne optimierungen, welche ja auch nicht für die Rekursion angewant wurden), so wird lediglich der Rekursionsbaum traversiert. Folglich hätte dann die iterative Variante das selbe Laufzeitverhalten.
Optimiert man die Algorithmen, so erhält man neue Berechnungsmethoden, und ein (hoffentlich) besseres Laufzeitverhalten. Aber es gelten immernoch die gleichen Bedingungen: Gibt es einen Algorithmus, der die n-te Fibonaccizahl in t(n) berechnet, so gibt es sowohl eine iterative, als auch eine rekursive Implementierung, die in Theta(t(n)) läuft.

Zitat:

Zitat von Delphi-Laie (Beitrag 1029121)
Erst in den Fällen 2 und 3 entfaltet die Rekursion ihr wahres Wesen: Sie ist elegant zu beschreiben (bzw. ist eine elgante Methode, Probleme zu lösen bzw. Problemlösungen darzustellen) und zu implementieren und führt zu kurzen, sicher auch gut wartbaren Quelltexten.

Das ist sogar auch bei 1. der Fall. Es gibt keine schönere Definition von Listen als die rekursive; insb. für theoretische Analysen.
Zitat:

Zitat von Delphi-Laie (Beitrag 1029121)
Das Laufzeitverhalten ist dagegen eher mau, denn diese Baumstruktur des Prorgrammablaufes beim Aufrufen der rekursiv aufgerufenen Unterprogramme x. Ordnung führen mit ziemlicher Sicherheit zu mindestens exponentiellem Laufzeitverhalten (bei der Fakultät z.B. sogar zu hyperexponentiellem Wachstum).

Die Laufzeit hängt von einem Algorithmus ab, nicht ob er rekursiv oder iterativ beschrieben wird. Beide sind gleichmächtige Beschreibungsformen. Der einzige Grund, warum Rekursion als langsamer empfunden wird als Iterationen ist der, dass 1. Die iterative Variante meist optimiert ist (Siehe bspw. Fibonacci), und 2. Ein Funktionsaufruf aufgrund der darunterliegenden Hardware länger braucht.
Zitat:

Zitat von Delphi-Laie (Beitrag 1029121)
Wollte man solche rekursiven Algorithem in adäquate iterative transformieren, so ist das entweder unmöglich (?) (1), sehr aufwendig (wie es hier jemand bezüglich Fibonacci andeutete)(2) oder nur unbefriedigend(3) (s. Quicksort, falls R. Sedgewicks Aussage immer noch aktuell ist) möglich.

Zu (1): Es ist (laut theoretischen Beweisen) immer möglich. Eine adäquate Implementierung wäre das iterative traversieren des Rekursionsbaumes. Inwiefern das aufwändig (2) ist, hängt eher von der Beschreibungssprache ab. Ob die Implementierung unbefriedigend (3) hängt in erster Linie von den Erwartungen ab. Lesbar ist eine solche generische Übertragung eher nicht; Aber das hängt in erster Linie von der Funktion ab, inwiefern diese eine lesbare iterative Implementierung erlaubt.


Was mir bisher eigentlich immer aufgefallen ist: Wenn ich mit Leuten über Rekursion ect. diskutiert habe, so waren das fast immer Leute, welche sich in erster Linie mit iterativen Programmiersprachen befasst haben. Vor 2 Jahren war ich rekursiven Implmentierungen zwar nicht abgeneigt, habe aber nur einen sehr scheuen und vorsichtigen Blick dahingewagt, immer im Hinterkopf, dass mir der dahinterliegende Code meinen Stack zumüllt.
Beginnt man, sich (gezwungenermaßen *g*) damit ordentlich außeinanderzusetzen, so lernt man damit umzugehen, und die Vorzüge kennenzulernen. Menschen, die die Ideen bspw. hinter Haskell, OCaml oder Lisp verstanden haben, musste ich noch nie von den Vorteilen von Rekursionen überzeugen - nur jene, die sich bisher noch nicht wirklich damit außeinandergesetzt haben.


greetz
Mike

Delphi-Laie 21. Jun 2010 10:52

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von JasonDX (Beitrag 1029157)
Zitat:

Zitat von Delphi-Laie (Beitrag 1029121)
1. Jedes Element enthält sein eigenes Abbild in der jeweils 1. Subebene nur einmal. So etwas ist z.B. bei der rekursiven Fakultät oder - im materiellen Bereich - bei den russischen Puppen namens Matrjoschka der Fall. Ich bleibe dabei, daß eine solche Rekursion nur eine „Lightversion“ ist, da sie letztlich mit der Iteration konformläuft.

Was genau meinst du mit "konformlaufen"? Dass sich die Rekursion auf einen iterativen Ablauf zurückführen lässt?

Zumindest die, die in Internetamateurenzyklopädie sicher aus gutem Grundes als „iterative“ Rekursion bezeichnet wird.

Zitat:

Zitat von JasonDX (Beitrag 1029157)
Dann ist jede Rekursion eine "Lightversion".

Das ist die entscheidende Frage. Jede Iteration läßt sich als Rekursion darstellen, denn letztlich rufen - in gewisser Weise - sich Schleifen auch nur selbst immer wieder auf.

Doch ist jede Rekursion auch als Iteration abbildbar? Dazu fehlen mir die Kenntnisse. Ist das schon bewiesen worden? In Robert Sedgewicks Standardwerk z.B. stand zur Quicksort, daß sich das nur unbefriedigend als Iteration darstellen/umsetzen läßt. Während der Implementation wurde mir rasch klar, daß mit der dort vorgestellten Quelltext letztlich nur die Stackhandhabung emuliert/simuliert wird, es also eine verkappte Rekursion ist.

Sollte die letzte Frage tatsächlich bejaht werden können, bliebe auf jeden Fall der Vorteil der kurzen, übersichtlichen Problem(lösungs)beschreibung sowie der Quelltexte mit gleichen Eigenschaften, zudem gut wart- und portierbarer Quelltexte.

Edit: Weiter oben schriebst Du, daß es laut „theoretischen Beweisen“ (Anmerkung: Derlei Beweise sind immer theoretisch) möglich sei. Das überlas ich zunächst.

Codewalker 21. Jun 2010 11:14

AW: Rekursion vs. Iteration
 
Ich habe auf die Schnelle keine Quelle gefunden, die es explizit auf Iteration zurückführt, aber es gibt Funktionen, die insbesondere im Compilerbau Kopfschmerzen machen, nämlich nicht-primitiv-rekursive Funktionen (Ackermannfunktion, Busy Beaver, Sudanfunktion, etc.).
Ich meine mich zu erinnern, dass man die nicht einfach auf eine iterative Variante zurückführen kann.

JasonDX 21. Jun 2010 12:00

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1030555)
Zitat:

Zitat von JasonDX (Beitrag 1029157)
Dann ist jede Rekursion eine "Lightversion".

Das ist die entscheidende Frage. Jede Iteration läßt sich als Rekursion darstellen, denn letztlich rufen - in gewisser Weise - sich Schleifen auch nur selbst immer wieder auf.

So einfach ist es leider nicht - bspw. sind nicht Schleifen wirklich das Problem, sondern aufeinanderfolgende Befehle. Aber über die rein theoretische Definition von TMs lässt sich das ganze einfacher in rekursive Ausdrücke überführen.

Zitat:

Zitat von Delphi-Laie (Beitrag 1030555)
Doch ist jede Rekursion auch als Iteration abbildbar? Dazu fehlen mir die Kenntnisse. Ist das schon bewiesen worden?

In den 30ern von Alonzo Church, durch die Turingvollständigkeit von Lambdaausdrücken. Eine etwas einfachere und verständlichere Variante wäre die iterative Traversierung von Rekursionsbäumen. Im Endeffekt arbeitet deine CPU auch nur iterativ, und simuliert lediglich rekursive Aufrufe.

Zitat:

Zitat von Delphi-Laie (Beitrag 1030555)
In Robert Sedgewicks Standardwerk z.B. stand zur Quicksort, daß sich das nur unbefriedigend als Iteration darstellen/umsetzen läßt. Während der Implementation wurde mir rasch klar, daß mit der dort vorgestellten Quelltext letztlich nur die Stackhandhabung emuliert/simuliert wird, es also eine verkappte Rekursion ist.

Inwiefern eine Umsetzung unbefriedigend oder zufriedenstellend ist, hängt in erster Linie von den Möglichkeiten und Erwartungen ab. Allerdings ist das dann nicht eine "verkappte Rekursion", sondern eine möglichst allgemein anwendbare Überführung eines rekursiven Ausdrucks in eine iterative Form.


Zitat:

Zitat von Codewalker (Beitrag 1030562)
Ich habe auf die Schnelle keine Quelle gefunden, die es explizit auf Iteration zurückführt, aber es gibt Funktionen, die insbesondere im Compilerbau Kopfschmerzen machen, nämlich nicht-primitiv-rekursive Funktionen (Ackermannfunktion, Busy Beaver, Sudanfunktion, etc.).
Ich meine mich zu erinnern, dass man die nicht einfach auf eine iterative Variante zurückführen kann.

Nichtprimitiv-rekursive Funktionen bieten nur dann Probleme, wenn der Compiler versucht, diese zu optimieren. Ansonsten ist die Überführung in eine iterative Variante für den Compiler nicht sonderlich schwierig. Auch wenns widersprüchlich klingen mag, aber der CALL-Befehl auf CPU-Ebene ist rein iterativ.
Was den genannten Busy Beaver betrifft: Der ist gar nicht berechenbar, somit gibts weder eine iterative, noch ne rekursive Beschreibung dieser Funktion.

greetz
Mike

Delphi-Laie 21. Jun 2010 13:06

AW: Rekursion vs. Iteration
 
Zitat:

Zitat von JasonDX (Beitrag 1030571)
Im Endeffekt arbeitet deine CPU auch nur iterativ, und simuliert lediglich rekursive Aufrufe.

Letztlich arbeitet eine (jede?!) CPU sogar nur sequentiell. Iterationen sind ja letztlich auch nur ein „Trick“, dem Prozessor immer und immer wieder das (fast) gleiche unterzuschieben.

Iterationen dienen der einfachen - hierarchiegleichen bzw. horizontalen - Wiederholung von Befehlen.

Rekursionen dienen der etas komplexeren, weil auf verschiedenen Hierarchieebenen befindlichen bzw. ablaufenden Wiederholung von Befehlen, sie sind sozusagen eine vertikale Iteration.

mkinzler 21. Jun 2010 13:08

AW: Rekursion vs. Iteration
 
Wobei der Mechanismus der Rekursion fest in den Prozessor verankert ist ( Stack)

negaH 21. Jun 2010 13:38

AW: Rekursion vs. Iteration
 
Zitat:

Letztlich arbeitet eine (jede?!) CPU sogar nur sequentiell.
Das ist eine Definitionsfrage. CPU=Central Processing Unit=Zentrale Recheneinheit. Wenn wir von einem Rechner=Computer ausgehen so ist die CPU der Kernbestandteil. Dieser könnte ein ASIC aber auch FPGA oder sogar ein ASIC mit internem FPGA sein. FPGAs arbeiten per se erstmal alles in parallel ab und nicht sequientiell. Wenn sequientiell dann weil es der Programmierer mit Hilfe eines Taktes so programmiert hat. Dh. relevante Teile eines Algorithmus können sehr wohl nicht-sequientiell also parallel ausgeführt werden.

Ergo: aus Sicht "Rekurson vs. Iteration", als Schreibweise eines Algorithmus in einer Programmiersprache, kann eine CPU diesen sehr wohl sequentiell wie eben auch nicht-sequentiell abarbeiten.

Beispiel: ein Algorithmus der auf der Boolschen Algebra basiert. Formal schreibt man diesen als Rekursive Formel und programmiert diesen auch exakt so in einem FPGA, in rekursiver Schreibweise. Die Synthese=Compiler, zerlegt diese Formel mit Hilfe der Boolschen Algebra über Matrizen in vollständig definiert Boolsche Ausdrücke. Daraus entsteht dann eine Verschaltung von elektronischen Gattern innerhalb des FPGAs. Man beschreibt also rekursiv das Verhalten einer Hardware. Obwohl also das Problem rekursiv formuliert wurde arbeitet die Elektronik im Zielsystem alles in parallel ab. Damit exitieren also keine Sprungbefehle, keine einzeln nacheinander abzuarbeitenden Befehlssequenzen und somit auch kein Stackframe und finally somit keine Benachteiligung in der Peformance und Resourcen der Schreibweisen "rekursiv vs. iterativ" eines Algos.

Gruß Hagen

idefix2 21. Jun 2010 15:03

AW: Rekursion vs. Iteration
 
Zitat:

Beispiel: ein Algorithmus der auf der Boolschen Algebra basiert. Formal schreibt man diesen als Rekursive Formel und programmiert diesen auch exakt so in einem FPGA, in rekursiver Schreibweise
Also darunter kann ich mir überhaupt nichts vorstellen. Könntest Du mit einem Beispiel illustrieren, was du meinst?

Zitat:

Wobei der Mechanismus der Rekursion fest in den Prozessor verankert ist ( Stack)
Der Hardwarestack wird von rekursiven Prozedure verwendet, ebenso wie von nicht rekursiven Prozeduren. Der Stack selbst hat mit Rekursion nichts zu tun, sondern nur mit Prozeduraufrufen. Deshalb brauchen natürlich auch rekursive Prozeduren einen Stack.

negaH 21. Jun 2010 15:41

AW: Rekursion vs. Iteration
 
Code:

  function XorVectorBits(Bits: std_logic_vector, Index: integer) return std_logic;
  variable
    Result: std_logic;
  begin
    Result := Bits(Index);
    if Index < Bits'High then
      Result := Result xor XorVetorBits(Bits, Index +1);
    end if;
    return Result;
  end function;

  function XorVextorBits(Bits: std_logic_vector) return std_logic;
  variable
    Result: std_logic;
    Index: Intger;
  begin
    Result := '0';
    for Index in Bits'Range loop
      Result := Result xor Bits(Index);
    end loop;  
    return Result;
  end function;
Oben sieht man zwei Funktionen in VHDL, erstere ist rekusiv die zweite nutzt eine Schleife. Beide beschreiben ein Verhalten einer späteren Hardware.

Das Signal Bits stellt man sich zb. wie ein Datenbus vor der aus zb. 16 Datenleitungen besteht. Die Boolsche Funktion lautet in Worten: Verknüpfe alle Datenleitungen in Bits per XOR und gebe das Resultat, ein Bit, zurück.

Beides wird bei der Synthese in Hardware exakt identische Resultate erzeugen. Nämlich ein XOR Gatter mit Bits'Range Inputs und einem Output.

Ok, es dürfte klar sein das das ein sehr enfaches Beispiel ist und hier der Vorteil in der formalen Schreibweise einer Rekursion noch nicht zum tragen kommt.

Gruß Hagen

idefix2 21. Jun 2010 16:18

AW: Rekursion vs. Iteration
 
Ich muss zugeben, dass mich das verblüfft. Ich hätte nicht geglaubt, dass es im wirklichen Leben tatsächlich Systeme gibt, die derartige rekurive Strukturen als Eingabe hernehmen und die Rekursion in parallel arbeitende Harware auflösen.

negaH 21. Jun 2010 21:47

AW: Rekursion vs. Iteration
 
Denke mal drüber nach warum ich in diesem Thread immer wieder betone das das nur eine Form einer Schreibweise ist und eben nicht direkt im Zusammenhang mit irgendwas Realem, wie eben Hardware, steht.

Rekursiv vs. Iterativ ist eine Frage der Schreibweise eines Algorithmus. Es ist nicht der Algorithmus selber noch dessen praktische Realisierung in Hardware.

Man muß immer strikt abstrahieren und eine Frage, je nach gewünschter Sichtweise, beantworten.

Bei "Rekursv vs. Iterativ" gilt erstmal das es da keinen Unterschied geben kann in der Performance und Speicherverbrauch. Erst wenn man die benutzte Hardware oder Softwaretools berücksichtig ändert sich die Antwort, bzw. erst dann macht es Sinn den Speicherverbrauch/Performance als Entscheidungskriterium heran zu ziehen. Aber..., dann bewertet man nicht mehr "Rekursiv vs. Iterartiv" sondern defakto die Fähigkeiten der btrachteten Softwaretools und Hardware, wie sie die unterschiedlichen Schreibweisen eines Algorithmus umzusetzen in der Lage sind.

Wer also behauptet: Rekursiv sei oft langsammer als Iterativ in der Performance oder eben mehr Speicher verbraucht auf Grund eines notwendigen Stackframes, der bewertet einen ASIC als Hardware, und eben nicht mehr objektiv zwei Schreibweisen eines Algos.

Gruß Hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:43 Uhr.
Seite 3 von 3     123   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz