| Programmieraufgaben Hier wird regelmäßig eine neue Programmieraufgabe gestellt, die dann gelöst werden soll und in Zusammenarbeit mit den Moderatoren auch besprochen werden kann. |
Diskussion: Türme von Hanoi im Forum Programmieraufgaben, in der Kategorie Code Kitchen; Anzeige Ok danke hab den Unterschied bemerkt. Trotzdem ist es in dem fall richtig weil die Aufgabenstellung es hier so ...
![]() |
| | #16 (permalink) |
| Registriert seit: 14.11.07 ![]() Likes: 0 | Anzeige Ok danke hab den Unterschied bemerkt. Trotzdem ist es in dem fall richtig weil die Aufgabenstellung es hier so verlangt, aber ich hab kapiert was du meinst. LG |
| | |
| | #17 (permalink) | |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 202 | Zitat:
Bps Fibonacci: nur weil die mathematische Definition rekursiv ist, muss man die ja nicht 1:1 übernehmen. Denn Code: public static long fib(int a){
if (a==1||a==2) return 1;
else return fib(a-1)+fib(a-2);
} Man vergleicht also Äpfel mit Birnen um dann festzustellen, dass Rekursion schlecht ist. jedenfalls, Fibonacci rekursiv: Code: static long fib(int a, long aktuell, long vorher)
{
long temp=aktuell;
aktuell=aktuell+vorher;
vorher=temp;
if (a>3) return fib(a-1, aktuell, vorher);
return aktuell+vorher;
} definiert man vorher/aktuell so: Code: {
long aktuell=0; long vorher=1;
static long fib(int a)
{
long temp=aktuell;
aktuell=aktuell+vorher;
vorher=temp;
if (a>3) return fib(a-1);
return aktuell+vorher;
}
}
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. | |
| | |
| | #18 (permalink) | |
| Moderator ![]() Registriert seit: 30.03.04 ![]() Likes: 14 | Hallo, Die iterative Lösung der Fib.-Zahlen ist schon besser. Möchte man große Fibonacci Zahlen rekursiv berechnen, selbst mit einer verbesserten rekursiven Formeln, kann dies zu erheblichen Problemen führen. Vermutlich erhält man dann irgendwann die Meldung, dass der Stack voll sei (+Programm bricht), da bei jedem Funktionsaufruf die entsprechenden Zeiger auf den Stack gelegt werden müssen. Verwendet man stattdessen eine normale Schleife, lassen sich eigentlich problemlos beliebig große Fibonacci-Zahlen berechnen, ohne gefahr zu laufen, dass einem der Stack explodiert. Auch wenn der Speicher/Stack u.ä. vernachlässigt werden könnte, wäre die iterative Variante schneller. Bei der rekursive Funktion habe ich min. zwei Sprünge, einmal in die Funktion und einmal wieder heraus. Bei der iterativen Formel habe ich aber pro Durchlauf nur einen Sprung + 1 Sprung für die Abbruchbedingung. D.h., rekursiv muss ich doppelt so oft springen wie bei der iterativen Variante, und Sprünge verbrauchen extrem viel Zeit. Aber ansonsten stimmt es, viele Algorithmen lassen sich extrem schön rekursiv lösen (z.B. alle Dateien in einem Ordner inkl. Unterordner auflisten (also Bäume durchlaufen)) und die iterative Variante macht bei diesen kaum/keinen Sinn und wirkt nur unheimlich aufbeläht. Kommt immer drauf an. Zitat:
Code: int fak(int n) {
if(n <= 0) return 1;
else return n*fak(n-1)
} | |
| | |
| | #19 (permalink) | |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 202 | Mir ist beim Essen eine viel schönere rekursive Fibonacciform eingefallen :Zitat:
z.B hier bei Fibonacci: bevor der Stack abraucht, bekommt man schon zig mal einen Überlauf von long&Co - ist also immer eine Abwägungssache. BTW: ich muss gerade an eine Mathestudentin denken, die in ihrem Zulassungsprojekt (DBS), um an das vorletze Datum mit einem zugehörigen Eintrag zu kommen sich rekursiv durch die ganze Tabelle gehangelt hat (die SQL Anfrage+bisschen Javacode sahen dafür ganz elegant aus ) - und den armen, schwächlichen (und wohl etwas mies konfigurierten) DB2 "Versuchsserver" ganz alleine blockierte. Ärgerlich für alle, die ihre Projekte vor der Abgabe noch testen wollten
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. | |
| | |
| | #20 (permalink) |
| Registriert seit: 21.06.11 ![]() Likes: 0 | Hey leute kann mir jemand sagen wie ich das auf C programmieren kann?? :-S ich verzweifle schon seit über ner Woche... ich komm einfach nicht weiter... |
| | |
| | #21 (permalink) |
| Registriert seit: 14.04.06 ![]() Likes: 4 | OT: Zu dem Rekursions-Ding möchte ich auch noch etwas beitragen. Wenn man die Fibonacci-Folge wie CDW implementiert, dann können moderne Compiler die Rekursion wegoptimieren (-> Tail Recursion). Damit sollte sich auch das Problem mit überlaufenden Stacks erledigt haben. Ich habe mal ein kleines Testprogramm geschrieben, das CDWs Implementation mit dieser iterativen vergleicht: Code: long fibi(long a)
{
long fib0 = 0, fib1 = 1, fib2, i;
for (i = 2; i < a; i++) {
fib2 = fib0 + fib1;
fib0 = fib1;
fib1 = fib2;
}
return fib2;
} Code: O0: rek clocks: 422393 itr clocks: 223544 O2: rek clocks: 50335 itr clocks: 51078 Os: rek clocks: 24751 itr clocks: 57327 Damit wird deutlich, dass der Compiler rekursive Programme in zumindest machen Fällen besser optimieren kann als iterative. Eine Verteufelung dieser ist damit meiner Meinung nach nicht gerechtfertigt. Die schnellste Implementation sollte übrigens diese sein: Code: long fib(long a)
{
const double phi = 1.6180339887498949;
const double sq5 = 2.2360679774997898;
return (long)(0.5 + pow(phi, a) / sq5);
} B2T: Auch die beiden (bisher ähnlich schon aufgetauchten) Hanoi-Varianten, rekursiv und iterativ, möchte ich noch einmal gegeneinander stellen. Code: long dummy = 0, dummy2 = 0;
void hanoi_r(a, b, c, h)
{
if (h > 1) {
hanoi_r(a, c, b, h-1);
hanoi_r(a, b, c, 1);
hanoi_r(b, a, c, h-1);
} else {
dummy += a - c;
//printf("Lege Scheibe von %d nach %d\n", a, c);
}
}
void hanoi_i(h)
{
int x;
for (x = 1; x < (1 << h); x++) {
int a = (x & x-1) % 3;
int c = ((x | x - 1) + 1) % 3;
dummy2 += a - c;
//printf("Lege Scheibe von %d nach %d\n", a, c);
}
} Eine Performance-Messung für eine Höhe von 28 ergibt bei mir folgende Ergebnisse: Code: unoptimiert (GCC 4.2.1): hanoi_r clocks: 3243513 hanoi_i clocks: 3290201 O3-optimiert (GCC 4.2.1): hanoi_r clocks: 1358059 hanoi_i clocks: 1584307 O3-optimiert (LLVM-GCC 4.2): hanoi_r clocks: 1085470 hanoi_i clocks: 1908822 Geändert von Eydeet (22.06.11 um 15:45 Uhr) |
| | |
![]() |
| - Anzeige - | |
| |
| Themen-Optionen | |
| Ansicht | |
| |
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| Türme von Hanoi (grafisch) in Java | Olli Kern | Code Kitchen | 2 | 24.06.04 12:42 |