Rekursiver Algorithmus für hanoieskes Problem |
28.01.2014, 21:39 | eman | Auf diesen Beitrag antworten » | ||||||||||
Rekursiver Algorithmus für hanoieskes Problem für die Uni muß ich einen rekursiven Algorithmus für ein Problem implementieren, das ähnlich den Türmen von Hanoi ist. Gegeben sind zwei gleich große Türme, es gibt drei Stäbe und Ziel ist es die Positionen der beiden Türme zu tauschen, also wo der schwarze war, soll der weiße stehen, und andersherum. Regeln sind wie beim normalen Türme von Hanoi und es dürfen gleich große Scheiben aufeinander liegen. Die Aufgabenstellung empfiehlt als status quo einen Zwischenstand, bei dem alle Scheiben rechts mit wechselnder Farbe sind (siehe Anhänge). Die rekursive Lösungsfunktion soll das gleiche Format haben wie die vom normalen Hanoi-Problem, also etwa moveTower( Stab from, Stab to, Zahl i, Stab temp). Folgendes habe ich nun seit ein paar Stunden erfolglos versucht: Für n=2 und n=3 explizite Lösungen probiert und versucht einen Rekursionsbaum aufzustellen. Leider ziemlich erfolglos... Daher wende ich mich nun an euch und hoffe, daß der ein oder andere einen hilfreichen Rat hat. Danke im Voraus, eman |
||||||||||||
28.01.2014, 21:49 | 10001000Nick1 | Auf diesen Beitrag antworten » | ||||||||||
Bitte nicht beachten, hier stand Unsinn. |
||||||||||||
28.01.2014, 23:07 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||||||
Geht es nur um irgendeinen Algorithmus, oder sogar um einen effizienten (d.h. mit minimaler Schrittzahl)? Ersteres ist ganz gut machbar, letzteres scheint mir ungleich schwerer. |
||||||||||||
28.01.2014, 23:24 | eman | Auf diesen Beitrag antworten » | ||||||||||
Es geht lediglich um irgendeinen Algorithmus. Leider stehe ich schon hierbei auf dem Schlauch. Ab dem Zwischenstand (siehe Bild oben), habe ich mir ungefähr folgende Strategie überlegt (Pseudocode):
Wenn ich also die untersten beiden Scheiben in Zielposition bringen möchte, muß ich zuerst (i-1) Scheiben auf den andren Haufen bringen, dann die eigentliche Scheibe verschieben und dann wieder (i-2) Scheiben auf den Ausgangshaufen (rechhts) zurückschaufeln... das müßte theoretisch funktioneren, oder? Nur wie komme ich zum sortierten Haufen rechts? |
||||||||||||
28.01.2014, 23:28 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||||||
Ich geb mal meine Idee an, zunächst das Problem zum Erstellen des "Zebraturms" in Bild 2:
Mit "move" meine ich einen Einzelschritt und mit "moveTower" die normale Hanoiturm-Prozedur. Tja, und zum Schluss alles "rückwärts", nur mit vertauschten Rollen der Stäbe für white und black. |
||||||||||||
29.01.2014, 00:02 | eman | Auf diesen Beitrag antworten » | ||||||||||
Vielen Dank für deine schnelle Antwort, HAL!
Ich bin einmal händisch die Schritte deines Algorithmus für i=2 durchgegangen, das endet leider in einem endlosen rekursiven bei moveTower( ..., 2*i -1, black), sobald man i=2 erreicht (und da muß man ja zwangsweise hin). |
||||||||||||
Anzeige | ||||||||||||
|
||||||||||||
29.01.2014, 07:37 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||||||
Das kann ich nur als Unfug bezeichnen. Erstens steht da moveTower( ..., 2*i -2, black), und zweitens ist moveTower die Hanoi-Prozedur, die bekanntlich nicht "endlos rekursiv" ist. Vielleicht verwechselst du ja moveTower mit der eigentlich hier definierten Hauptprozedur mergeTowers. Als Ergänzung daher noch - obwohl ich schon angenommen und vorausgesetzt hatte, dass du die kennst - die normale Hanoi-Prozedur:
|
||||||||||||
29.01.2014, 09:47 | eman | Auf diesen Beitrag antworten » | ||||||||||
Hallo HAL 9000, entschuldige bitte meinen groben Unfug, ich habe tatsächlich moveTower mit mergeTower verwechselt... Dein Algorithmus funktioniert tatsächlich wunderbar, auch wenn sich meinem bescheidenen Denkvermögen entzieht, wie du auf ihn gekommen bist. Ich habe den Solver jetzt durch zweimaliges Aufrufen deines Zebraalgorithmus implementiert, etwas unschön mit Stack umstapeln und schmutzig implementiertem Richtungswechsel, aber es funktioniert. Man könnte den Algorithmus im Nachgang ein wenig beschleunigen, indem man Schritte, die sich gegenseitig aufhaben rauslöscht und Schritte die konsekutiv die gleiche Scheibe adressieren zusammenfaßt. Ich danke dir tausendfach, HAL 9000!! Du hast meinen Tag gerettet! Edit: Den klassischen Türme von Hanoi-Algorithmus kenne ich natürlich, was mich aber nicht daran gehindert hat, ihn falsch zu implementieren ;-) |
||||||||||||
29.01.2014, 11:00 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||||||
Ja, die obige Prozedur ist noch ziemlich ineffizient. Deutlich besser wäre da
moveDoubleTower macht folgendes: Es setzt den Zebraturm der Höhe 2j von Position from zu Position to um, dabei wird aber (im Gegensatz zum Original-Hanoi) die Reihenfolge wsws...ws in swsw...sw umgewandelt, bzw. umgekehrt! Da wir das ganze aber ja zweimal in einer Iteration aufrufen, hebt sich das wieder auf, und der Turm ist wieder in der "richtigen" Farbreihenfolge. Das ganze benötigt nun nur noch Schritte, oben waren es noch Schritte. Optimal ist aber auch das noch nicht. EDIT: Die komplette Prozedur wäre dann, alle Schritte nochmal in der umgekehrten Richtung durchzuführen, aber dabei black und white zu vertauschen - insgesamt also
EDIT: Hmmm, ist viellleicht doch noch ein Denkfehler drin mit dieser Geschichte wsws...ws bzw. swsw...sw, also vergiss es erstmal. |
||||||||||||
29.01.2014, 11:42 | eman | Auf diesen Beitrag antworten » | ||||||||||
Ja, dein letzter Algorithmus ist deutlich schneller und für mich verständlicher (da sich die Bedeutung von from, to und temp bzw. white, black und mixed nicht bei jedem Aufruf ändert); leider ist er allerdings nicht mehr rekursiv, wie die Aufgabenstellung es fordert. Wahrscheindlich kann man noch ein bißchen an Zügen dadurch wegzaubern, daß man die Mixed-Pyramide nur so groß macht, wie gerade nötig. Nocheinmal danke für deine Hilfe! Edit:
Also meine ein zu eins implementierung deines zweiten MergeTowers funktioniert einwandfrei. |
||||||||||||
29.01.2014, 11:45 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||||||
Mein letztes EDIT war unnötige Panikmache, es geht also doch, aber meine Beschreibung oben ist falsch: moveDoubleTower vertauscht nicht generell die w- und s-Scheiben gleicher Größe, sondern nur bei den beiden untersten Scheiben, d.h. wswsws...ws wird zu swwsws...ws bzw. beim zweiten Aufruf dann swwsws...ws wieder zurück in wswsws...ws. Und dann noch zu dem "Problem" ( ):
Da mein erster Wurf oben von mergeTowers sich selbst nur einmal (mit i-1 und ansonsten gleichen Aufrufparametern) aufruft, habe ich das gleich lieber in eine Schleife umgewandelt - da bin ich zu sehr "praktischer" Programmierer: Zuviel Iterationstiefe belastet den Stack zu sehr, d.h. wenn möglich, bitte vermeiden. Inhaltlich äquivalent kannst du das ganze natürlich zu
umschreiben. |
|
Verwandte Themen
Die Beliebtesten » |
|
Die Größten » |
|
Die Neuesten » |
|