Schreiben Sie eine Funktion / Subroutine, um eine Liste von Ganzzahlen im Tower of Hanoi- Stil zu sortieren .
Sie erhalten einen Stapel ganzer Zahlen. Dies ist der Hauptstapel.
Sie erhalten auch zwei weitere Helferstapel. Diese Hilfsstapel haben jedoch eine einzigartige Eigenschaft: Jedes Element muss kleiner oder gleich groß sein wie das Element darunter. Der Hauptstapel unterliegt keiner solchen Einschränkung.
Sie müssen den Hauptstapel an der richtigen Stelle sortieren und die größten Ganzzahlen darunter platzieren. Ihre Funktion / Subroutine gibt die Anzahl der Bewegungen zurück, die sie beim Sortieren des Stapels ausgeführt hat.
Hinweis: Sie müssen den Hauptstapel an Ort und Stelle sortieren, nicht auf einen anderen Stapel sortieren und das als Antwort bezeichnen. Wenn Sie dies jedoch aus irgendeinem Grund nicht tun können, können Sie die veränderlichen Stapel simulieren. Es gibt nur 3 Heringe und nur 1 Hering kann ungeordnet sein.
Ihre Funktion / Subroutine kann jeden Stapel jederzeit inspizieren, aber sie kann nur durch Aufspringen und Drücken eine Bewegung ausführen. Ein einzelner Zug ist ein Pop von einem Stapel, der auf einen anderen geschoben wird.
Testen Sie Ihre Funktion / Subroutine für jede Permutation der ersten 6 natürlichen Zahlen. Mit anderen Worten, testen Sie Ihre Funktion / Subroutine auf {1},{2},...,{6},{1,1},{1,2},...,{1,6},{2,1},...
(dies sollten insgesamt oder Möglichkeiten sein (danke an Howard für die Korrektur meiner Mathematik)). Die Funktion / Subroutine, die Elemente am seltensten bewegt, gewinnt.61+62+...+66
55986
quelle
6**1+6**2+...+6**6=55986
Elemente.Antworten:
Java - optimale Lösung (1080544 Züge)
Diese Lösung erstellt einen Baum mit dem kürzesten Pfad vom Ziel und zurück und überquert dann den Pfad vom Anfangszustand zum Ziel. Viel Raum für Geschwindigkeitsverbesserungen, aber dennoch sind alle 55986-Probleme in etwa einer Minute erledigt.
Vorausgesetzt, der Algorithmus ist korrekt implementiert, sollte dies die theoretisch beste Lösung sein.
quelle
C - 2547172 für 55986 Eingänge
Hier gibt es viel Raum für Verbesserungen. Aus Gründen meiner eigenen Gesundheit habe ich dies vereinfacht, sodass es nur möglich war, das oberste Element jedes Stapels zu überprüfen. Die Aufhebung dieser selbst auferlegten Beschränkung würde Optimierungen wie die Bestimmung der endgültigen Reihenfolge im Voraus und den Versuch ermöglichen, die Anzahl der dafür erforderlichen Züge zu minimieren. Ein überzeugendes Beispiel ist, dass meine Implementierung das Worst-Case-Verhalten aufweist, wenn der Hauptstapel bereits sortiert ist.
Algorithmus:
Analyse:
quelle
Python,
39838383912258 bewegt sich über 55986 EingabenDas ist sehr ineffizient.
Ich werde die Gesamtzahl der Züge addieren, nachdem das OP geklärt hat, ob sie für alle diese Fälle oder für bestimmte andere Fälle gelten.
Erläuterung
Was, Kommentare nicht gut genug für dich?
Hinweis für OP: Vielen Dank, dass Sie diesen Code-Golf nicht gemacht haben.
quelle
[2,1,1]
eine Möglichkeit,[2,1,1].index(1)
als 2 zu beginnen, dh vom oberen Ende?[2,1,1,3,5].index(1)==2
statt1
list.index(data)
gibt den Index des Elementsdata
in zurücklist
. Ich nicht kenne den Indexdata
also1
len(list)-(list[::-1].index(1))
Python:
1.688.2931.579.1821.524.0541.450.8421.093.195 ZügeDie Hauptmethode
main_to_help_best
besteht darin, einige ausgewählte Elemente vom Hauptstapel zum Hilfsstapel zu verschieben. Es hat ein Flag,everything
das definiert, ob alles in den angegebenen Bereich verschoben werdendestination
soll oder ob nur der größte Bereich beibehalten werden soll,destination
während der Rest im anderen Helfer enthalten sein soll.Angenommen, wir
dst
verwenden Helferhelper
, kann die Funktion grob wie folgt beschrieben werden:helper
rekursivdst
helper
zur Hauptleitungdst
everything
gesetzt, verschieben Sie die Elemente in main rekursiv nachdst
b. Andernfalls verschieben Sie Elemente in main nach rekursiv
helper
Der Hauptsortieralgorithmus (
sort2
in meinem Code) ruft dannmain_to_help_best
mit aufeverything
set toFalse
und verschiebt dann das größte Element zurück nach main und verschiebt dann alles vom Hilfsprogramm zurück nach main, wobei es sortiert bleibt.Weitere Erläuterungen als Kommentare in den Code eingebettet.
Grundsätzlich sind die Prinzipien, die ich verwendet habe:
Prinzip 3 wird implementiert, indem die Bewegung nicht mitgezählt wird, wenn die Quelle das vorherige Ziel ist (dh wir haben gerade main zu help1 verschoben, dann möchten wir von help1 zu help2 wechseln), und wir reduzieren die Bewegungszahl um 1, wenn wir Bewegen Sie ihn zurück in die ursprüngliche Position (dh main zu help1, dann help1 zu main). Wenn
n
alle vorherigen Züge dieselbe Ganzzahl haben, können wir diesen
Züge auch neu anordnen. Das nutzen wir auch, um die Anzahl der Züge weiter zu reduzieren.Dies ist gültig, da wir alle Elemente im Hauptstapel kennen. Dies kann also dahingehend interpretiert werden, dass wir das Element in Zukunft zurückschieben werden. Wir sollten diese Verschiebung nicht vornehmen.
Probelauf (Stapel werden von unten nach oben angezeigt - das erste Element ist also die Unterseite):
Wir können sehen, dass der schlimmste Fall ist, wenn das größte Element auf der zweiten Unterseite platziert wird, während der Rest sortiert wird. Im schlimmsten Fall können wir sehen, dass der Algorithmus O (n ^ 2) ist.
Die Anzahl der Züge ist offensichtlich für
n=1
undn=2
wie wir aus dem Ergebnis ersehen können, minimal , und ich glaube, dass dies auch für größere Werte von minimal istn
, obwohl ich es nicht beweisen kann.Weitere Erklärungen finden Sie im Code.
quelle
4
. Was ist das Speichern des zweitgrößten Elements auf dem zweiten Helfer? Was bedeutet das?Java -
21290902083142 bewegt sich auf 55986 ArraysDie ideone Verbindung .
Das Framework, um sicherzustellen, dass der Algorithmus korrekt ist:
Der eigentliche Algorithmus:
Der Testfall:
quelle
C / C ++ hat keine Bewegungen gemessen (pegs: p1, p2, p3). Sie wissen nicht, wie Sie C ++ - Code hinzufügen, der STL verwendet (Formatierungsproblem). Teile des Codes aufgrund von HTML-Tag-Formaten im Code verlieren.
Führen Sie die Verschiebungsdaten (n + m) in p2 & p3 zu p1 zusammen.
quelle
hanoi(...)
Funktion nicht. Außerdem haben Sie 2#include
s, die nicht kompiliert werden. Bitte posten Sie den vollständigen Code.