Gerade als ich Floyds Zykluserkennungsalgorithmus vorschlagen wollte, schlug mich Ricis Beitrag. Das Ganze kann jedoch praktischer gestaltet werden, indem Vergleiche von Vollzuständen beschleunigt werden.
Der Engpass des vorgeschlagenen Algorithmus wäre der Vergleich des vollständigen Zustands. Diese Vergleiche werden in der Regel nicht beendet, sondern hören früh auf - beim ersten Unterschied. Eine Optimierung besteht darin, sich zu merken, wo die früheren Unterschiede aufgetreten sind, und diese Teile des Zustands zuerst zu überprüfen. Führen Sie beispielsweise eine Liste mit Standorten, und gehen Sie diese Liste durch, bevor Sie einen vollständigen Vergleich durchführen. Wenn ein Ort aus dieser Liste einen Unterschied aufdeckt, stoppen Sie den Vergleich (mit Fehler) und verschieben Sie den Ort an den Anfang der Liste.
Ein anderer (und möglicherweise besser skalierbarer) Ansatz ist die Verwendung von inkrementellem Hashing. Wählen Sie eine Funktion für den vollständigen Status, sodass die Hash-Werte in O (1) leicht angepasst werden können, wenn sich ein Teil des Status ändert. Nehmen Sie zum Beispiel eine gewichtete Summe von Zustandswörtern mit einer großen Primzahl und verknüpfen Sie sie mit der ungewichteten Summe mit einer anderen großen Primzahl (Sie können auch eine modulare gewichtete Summe von Wortquadraten mit unterschiedlicher Gewichtung und unterschiedlichem Modul eingeben). Auf diese Weise dauern Hash-Aktualisierungen bei jedem Ausführungsschritt 0 (1) und Vergleiche 0 (1), bis Sie einen Treffer erhalten. Die Wahrscheinlichkeit eines falschen Positivs (dh die Hashes stimmen überein, während sich die Zustände unterscheiden) ist sehr gering, und selbst wenn dies jemals passiert, wird es sich über eine große Anzahl von echten Negativen amortisieren (falsche Negative sind unmöglich).
Natürlich scheint es in der Praxis wahrscheinlicher zu sein, dass es zu Situationen kommt, in denen Ziffern der Zahl pi generiert werden - Dinge ändern sich ständig, enden aber nie. Eine andere häufige Möglichkeit besteht darin, dass die Endlosschleife Speicher zuweist. In diesem Fall erschöpft sie schnell den gesamten verfügbaren Speicher.
In meinem Kurs über Algorithmen und Datenstrukturen muss sich unser Autograder mit Studentenbeiträgen befassen, die manchmal in Endlosschleifen geraten. Dies wird durch ein 30-Sekunden-Timeout und ein bestimmtes Speicherlimit behoben. Beide sind weitaus lockerer als das Laufzeit- und Speicherbudget, das wir im Rahmen der Einstufung festlegen. Ich bin mir nicht sicher, ob die Implementierung einer echten Endlosschleifenerkennung in diesem Zusammenhang sinnvoll ist, da solche Programme etwas langsamer ausgeführt werden (hier könnte die Hardwareunterstützung für State-Hashing helfen, aber auch hier wären zusätzliche Verwendungszwecke erforderlich) begründen dies). Wenn die Schüler wissen, dass ihr Programm abgelaufen ist, können sie normalerweise die Endlosschleife finden.