Slitherlink oder Suriza (japanisch スリザーリンク - surizā rinku) ist ein japanisches Puzzle. Es wurde erstmals 1989 vom Sudoku-Herausgeber Nikoli veröffentlicht. Es ist ein nachgewiesen NP-vollständiges Problem[1].
Das Spielfeld ist ein m x n Gittergraph. In den Zellen können Zahlen von 0 bis 3 stehen. Das Ziel ist es, benachbarte Knoten so zu verbinden, dass ein Zyklus entsteht. Dabei gilt es, die folgenden drei Regeln zu beachten:[2]
Gute Slitherlink-Puzzles haben eine eindeutige Lösung. In Abbildung 1[3] ist ein kleines Slitherlink-Puzzle dargestellt.
Es wird nach den selben Regeln gespielt, aber das Spielfeld besteht aus Hexagonen. Die Zahlen in den Zellen können entsprechend größer sein. In dem Beispiel aus Abbildung 2[4:1] gibt es auch Zellen mit der Nummer 4 oder 5.
Es gilt neben den Standardregeln noch die Zusatzregeln, dass es keinen 2x2 Bereich an Zellen innerhalb des Zyklus geben darf. Lösungen die zuvor bei Slitherlink möglich waren, können dadurch wie in Abbildung 3[5:1] verboten werden.
Die Slitherlink-Regeln werden um die Folgenden ergänzt:
Für gewöhnlich geht man so vor, dass man damit beginnt kleinere eindeutige Teillösungen zu bestimmen, um diese dann zu einem geschlossenen Kreis zu verbinden[7]. Zudem ist es sinnvoll, Linien auszustreichen, die nicht Teil der Lösung sein können. In Abbildung 5[2:1] ist die Progression beim Lösen von Slitherlink exemplarisch dargestellt.
Für den Fall, dass die Anzahl ausgewählter Linien mit der Nummer einer Zelle übereinstimmt, können alle anliegenden und noch nicht gewählten Kanten ausgeschlossen werden. Dies ist bei Zellen mit der Nummer 0 wie in Abbildung 6[8] leicht zu erkennen.
Die Erkenntnis, dass jeder Knoten nur 0 oder 2 angrenzende Linien hat, führt zu vielen verschiedenen Deduktionsstrategien, wie z.B. die Folgenden.
Zellen mit 3:
Diese Regel gilt nicht für triviale Slitherlink-Puzzles, welche durch einen einfachen Zyklus um zwei benachbarte 3-Zellen gelöst werden können, weil es keine anderen Zahlen gibt.[9]
Zellen mit 1:
Spielfeldecken:
Basierend auf dem SIMPATH-Algorithmus zur Repräsentation von s-t Pfaden als ZDD haben Yoshinaka et. al.[10] einen Solver für Instanzen von Slitherlink entworfen. Es soll ein ZDD generiert werden, welches alle Lösungen für eine gegebene Slitherlinkinstanz darstellt. Mit anderen Worten sollen alle Zellen entsprechend ihrer Zahl abgedeckt sein.
Eine Instanz für Slitherlink ist ein Tupel aus einem Eingabegraphen und einer partiellen Funktion , wobei . Für ein bedeutet dabei, dass genau Kanten aus in der Lösung enthalten sein müssen. Eine Lösung für eine gegebene Instanz ist ein Kreis unter der Bedingung, dass für alle aus der Definitionsmenge von gilt.
initialize mate;
initialize count;
create root labeled with first edge;
create 0-terminal, 1-terminal;
Q = new Queue;
Q.enqueue(root);
while Q not empty
node = Q.enqueue;
e = edge node is labeled with;
if node has fixed end or is incompatible with h
create 0-arc from node to 0-terminal;
else
childnode = create new node;
create 0-arc from node to childnode;
if taking e forms a cycle matching h
create 1-arc from node to 1-terminal;
else if taking e declines state of n or is incompatible with h
create 1-arc from node to 0-terminal;
else
childnode = create new node;
create 0-arc from node to childnode
Der Algorithmus iteriert ähnlich wie SIMPATH in einer Art Breitensuche über die Kanten. Auch hier müssen die Kanten zunächst in einer totalen Ordnung sein.
Es wird eine Funktion anstelle der -Tabelle verwendet, um den Zustand eines Knoten im ZDD zu speichern. bedeutet, dass die Funktion nur für Knoten aus Kanten definiert ist, die entsprechend der Kantenordnung größer oder gleich der aktuell betrachteten Kante sind. Informationen über bereits untersuchte Kanten müssen also nicht gemerkt werden. Dabei gilt:
Neben der -Funktion gibt es eine Funktion für jeden Knoten des ZDDs. Diese Funktion zählt für alle in der Definitionsmenge von , die Anzahl bereits abgedeckter Kanten. Am Anfang, wenn noch keine Kanten ausgewählt wurden, ist für alle .
Intitial ist für alle definiert als . Wie bei SIMPATH werden zu Beginn der Wurzelknoten und die Endknoten (0-terminal und 1-terminal) generiert und dann alle Kanten über die Queue iteriert. Für jeden Knoten, der neu generiert wird und in die Queue hinzugefügt wird, wird zusätzlich der Zustand mit und gespeichert. Nachdem alle Kanten untersucht wurden, werden die Lösungen durch den 1-terminal Knoten repräsentiert, d.h. alle gültigen Pfade zu 1-terminal repräsentieren eine Lösung für die Slitherlinkinstanz.
mate updaten:
Nach Wahl einer Kante (1-arc) wird wie folgt angepasst:
Außerdem wird der Definitionsbereich von so angepasst, dass nur noch Knoten aus betrachtet werden. Also nur noch Knoten größer oder gleich der nächsten zu untersuchenden Kante . Dies gilt unabhängig davon, ob die Kante gewählt wird oder nicht (0-arc und 1-arc).
count updaten:
Nach Wahl einer Kante (1-arc), wird der Zähler für jedes um 1 erhöht, wenn .
Definitionen:
Es gibt einen festen Endpunkt für eine Kante , wenn und für ein .
Der Zustand eines Knoten ist inkompatibel mit , falls es ein gibt, sodass oder , wobei alle Kanten meint, die gemäß Ordnung größer als die aktuelle Kante sind. Der Zustand ist also inkompatibel, wenn entweder eine Zelle "überabgedeckt" ist oder mit den noch zu untersuchenden Kanten nicht mehr alle Zellen abgedeckt werden können.
Das Auswählen einer Kante erzeugt einen Kreis, wenn für alle falls und oder falls .
Das Auswählen einer Kante erfüllt , wenn alle Zellen genau abgedeckt sind ().
Das Auswählen einer Kante wird abgelehnt, wenn , , oder .
Folgezustände erkennen:
Innerhalb der while-Schleife (Z. 8-21 im Pseudocode) werden verschiedene Bedingungen geprüft, um den passenden Folgeknoten im ZDD für den 0-arc bzw. 1-arc zu finden.
Fall 1: Die aktuelle Kante soll nicht ausgewählt werden (0-arc).
Fall 2: Die aktuelle Kante soll ausgewählt werden (1-arc).
Beispiele:
Das einfache Beispiel in Abbildung 12 wird betrachtet und verschiedene Zustände, die bei der Anwendung des Algorithmus auftreten werden, werden untersucht. Die Kantenordnung wird entsprechend der angegebenen Knotennummerierung betrachtet, z.B. . Seien und die Belegung der Funktionen nach der Auswahl einer Kante (1-arc). Für dieses Beispiel gibt es 4 verschiedene Beschränkungen für die umliegenden Linien der Zellen. Sei wie folgt definiert:
| j | m | ||||
|---|---|---|---|---|---|
| 2 | 5 | 1 2 3 4 5 6 7 8 9 | 1 5 3 4 2 6 7 8 9 | 0 0 0 0 | 1 1 0 0 |
Der Zustand des Knoten ist inkompatibel mit . Für ist . Die nächste zu untersuchende Kante wäre , d.h. . Falls auch die Kante nicht genommen wird, gibt es nur noch eine Kante, um zu erreichen, aber zwei wären notwendig. Nicht-Wahl der Kante führt also zur Unlösbarkeit, der 0-arc führt zu 0-terminal.
Allerdings führt das Auswählen von auch zur Unlösbarkeit. ist die letzte Kante über den Knoten des Eingabegraphen. Um einen Kreis zu erzeugen, wird jedoch eine weitere Kante mit als Endpunkt benötigt. Die nächste Kante gemäß Kantenordnung wäre , d.h. für ist . Es gibt einen festen Endpunkt, also führt auch der 1-arc zu 0-terminal.
| j | m | ||||
|---|---|---|---|---|---|
| 2 | 5 | 0 0 4 3 5 6 7 8 9 | - | 2 1 0 0 | - |
Das Auswählen von wird abgelehnt, denn . Der Knoten des Eingabegraphen wurde bereits zweimal besucht, ein drittes Mal ist verboten. Der 1-arc führt also zu 0-terminal. Die Nicht-Wahl (0-arc) von ist hingegen in diesem Fall möglich und ein neuer Knoten im ZDD wird generiert.
| j | m | ||||
|---|---|---|---|---|---|
| 8 | 9 | 0 0 0 0 5 0 0 9 8 | - | 2 2 2 1 | 2 2 2 2 |
Die Wahl von erzeugt einen Kreis, denn , , und sonst. Außerdem ist für , , und , wird also erfüllt. Es wurde eine Lösung für die Slitherlinkinstanz gefunden, es führt ein 1-arc zu 1-terminal.
Bei einen guten Slitherlink-Puzzle mit nur einer Lösung, kann der Algorithmus bei dem ersten -erfüllenden gefundenen Kreis abgebrochen werden.
Die Autoren haben ihren Algorithmus für verschiedene Instanzen mit dem SAT-Solver Sugar und dem Integer Programming Solver CPLEX verglichen. Im Ergebnis schlägt der ZDD-Algorithmus für viele Instanzen Sugar. Es gibt auch Beispiele, bei denen Sugar zeiteffizienter war. CPLEX ist in manchen Fällen schneller. Die Instanzen wurden auch mit einem heuristische Solver slink getestet. Dieser war für alle Instanzen deutlich schneller. Laut den Autoren seien diese Ergebnisse damit zu erklären, dass Sugar und CPLEX eher für allgemeinere Zwecke entwickelt wurden, während slink speziell für Slitherlink designt wurde und die ZDD-Lösung eher dazwischen liegt.
| Instance | Graph size | Time Sugar | Time CPLEX | Time ZDD-Algo | Time slink |
|---|---|---|---|---|---|
| BS1 | 11x11 | 5,460 | 0,07 | 0,116 | 0,001 |
| BS12 | 11x11 | 4,696 | 0,28 | 0,384 | 0,004 |
| BS25 | 11x11 | 6,496 | 0,12 | 0,060 | 0,001 |
| BS37 | 11x11 | 8,773 | 0,14 | 0,044 | 0,004 |
| BS43 | 19x11 | 8,349 | 0,17 | 0,060 | 0,001 |
| BS54 | 19x11 | 7,380 | 0,40 | 0,304 | 0,008 |
| BS68 | 25x15 | 12,433 | 0,39 | 0,384 | 0,004 |
| BS77 | 25x15 | 13,281 | 0,90 | 0,376 | 0,004 |
| BS89 | 37x21 | 48,035 | 1,56 | 9,329 | 0,016 |
| BS96 | 37x21 | 186,612 | 3,07 | 26,286 | 0,104 |
| S10 | 37x21 | 1411,944 | 41,43 | 4569,330 | 0,036 |
| C95 | 32x46 | 1076,839 | 95,93 | - | 0,088 |
Laufzeit angegeben in Sekunden für das Lösen von Slitherlink. Für C95 konnte der ZDD-Solver keine Lösung finden aufgrund nicht ausreichenden Speichers.
Eine Lösungsmöglichkeit ist der Constrained-Based Ansatz dabei generiert man aus einem gegebenen Spielfeld eine aussagenlogische Formel und sucht eine Lösung mithilfe von bekannten SAT oder SMT Solvern. Miyauchi und Tanaka[11] haben eine SMT-Lösung entwickelt, die für einige Fälle bessere Ergebnisse als vorherige Slitherlink-Solver erreichen konnte.
T. Yato und T. Seta, "Complexity and completeness of finding another solution and its application to puzzles," IEICE transactions on fundamentals of electronics, communications and computer sciences, Jg. 86, Nr. 5, S. 1052–1060, 2003. pdf ↩︎
Nikoli. "Slitherlink.” https://www.nikoli.co.jp/en/puzzles/slitherlink/ ↩︎ ↩︎
Wikipedia. "Suriza." https://de.wikipedia.org/wiki/Suriza ↩︎
puzzlephil. "Slitherlink-Specials." https://puzzlephil.com/puzzles/slitherlinkspecials/de/ ↩︎ ↩︎
janko. "No-Square Slitherlink." https://www.janko.at/Raetsel/Varianten/017.a.htm ↩︎ ↩︎
janko. "Colorlink." https://www.janko.at/Raetsel/Varianten/019.a.htm ↩︎ ↩︎
Wikipedia. "Slitherlink." https://en.wikipedia.org/wiki/Slitherlink#Solution_methods ↩︎
Conceptis. "Slitherlink Techniken." https://www.conceptispuzzles.com/de/index.aspx?uri=puzzle/slitherlink/techniques, ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
D. Westreicher, „Slitherlink Reloaded," Bachelorarbeit, 2011. pdf ↩︎
R. Yoshinaka, T. Saitoh, J. Kawahara, K. Tsuruma, H. Iwashita und S. Minato, "Finding All Solutions and Instances of Numberlink and Slitherlink by ZDDs," Algorithms, Jg. 5, Nr. 2, S. 176–213, 2012, doi: 10.3390/a5020176. pdf ↩︎
T. Miyauchi und K. Tanaka, "Solving Slitherlink with FPGA and SMT Solver," Journal of Information Processing, Jg. 28, S. 959–969, 2020, doi: 10.2197/ipsjjip.28.959. pdf ↩︎