Ein polynomieller Algorithmus für das N-Damen Problem 1 Einführung Der folgende Vortrag basiert auf dem Text A Polynomial Time Algorithm for the N-Queens Problem von Rok Sosic und Jun Gu aus dem Jahre 1990. Bei dem n-damen Problem handelt es sich um ein klassisches kombinatorisches Problem. Die Dame ist eine Spielfigur aus dem Schach, die waagerecht, senkrecht und diagonal andere Figuren schlagen kann. Nun stellt man sich die Frage, wieviele Damen man auf einem Feld der Größe n n platzieren kann, ohne dass sich die Damen gegenseitig schlagen können, d.h. dass auf jeder Waagerechten, Senkrechten und Diagonalen befindet sich genau eine Dame. Eine Antwort auf die Frage wird z.b. in Ahrens - Mathematische Unterhaltungen und Spiele von 1921 gegeben. 2 Das n-damen Problem Das 4-Damen Problem ist die kleinste lösbare Instanz. Das Problem besteht also darin, 4 Damen auf einem Schachfeld der Größe 4 4 zu stellen, ohne dass sich die Damen gegenseitig schlagen können. Damit darf in jeder Zeile, Spalte und Diagonalen des Feldes jeweils nur eine Dame stehen. Das n-damen Problem besteht darin, n Damen auf einem Feld der Größe n n zu stellen, ohne dass sie sich gegenseitig schlagen können. Eine Lösung des n-damen Problems kann durch ein n-tupel (q 1,..., q n ) {1,..., n} n parametrisiert werden. Da in jeder Zeile höchstens eine Dame stehen darf, aber n Damen verteilt werden müssen, befindet sich schon in jeder Zeile eine Dame. q i gibt die Spalte der Dame an, die in der i-ten Zeile steht. In dem Buch von w. Ahrens - Mathematische Unterhaltungen und Spiele wird eine Methode beschrieben, die eine Lösung für das n-damen Problem aus Lösungen für kleinere Probleme zusammensetzt. Diese Lösungsmethode entspricht dem Prinzip des Divide-And-Conquer und hat den Nachteil, dass nur eine ganz bestimmte Klasse von Lösungen erzeugt werden kann. Dies passiert nicht bei einem Suchbasierten Algorithmus. Eine Möglichkeit, eine Lösung zu finden, besteht im Backtracking. Dabei wird mit der Platzierung einer Dame begonnen und sukzessive werden weitere Damen platziert, bis eine Lösung gefunden wird oder eine Kollision entsteht, dann wird die letzte Dame umplatziert und man fährt fort. Da ein solcher Algorithmus sicherlich im worst case exponentielle Laufzeit hat, eignet er sich nicht für große Instanzen des n-damen Problems. Neuere Untersuchungen haben ergeben, dass man das n-damen Problem so nur bis zur Instanz n = 100 in angemessener Zeit lösen kann. Damit ist es selbstverständlich sinnvoll, nach einem schnelleren Algorithmus 1
zu suchen. Im nächsten Teil werden wir einen neuen probalistischen lokalen Suchalgorithmus angeben, der auf einer gradientenbasierten Heuristik beruht. Der Algorithmus benötigt nur polynomielle Zeit, benutzt kein Backtracking und findet ein Lösung für große n-damen Probleme in einer angemessenen Zeit. 3 Der Algorithmus Sei: 1.π(i)(i = 1,..., n) eine Permutation aus S n = {f : {1,..., n} {1,..., n} f bijektiv} 2.(z i, s π(i) ) (i = 1,..., n) die n Koordinaten der Positionen von n Damen auf einem Schachbrett Da in jeder Zeile nur eine Dame stehen darf, reicht es vollkommen mit π(i) die Spaltenposition der Dame in der i-ten Zeile zu bezeichnen. Dieses n-tupel kann man in einem Array der Größe n speichern. Für jede Permutation π S n wird so garantiert, dass sich in jeder Zeile und Spalte jeweils nur eine Dame befindet. Eine Kollision kann also nur in den Diagonalen auftreten. Der neue Algorithmus sieht wie folgt aus: 1 function queen search ( queen : array [ 1.. n ] of integer ) 2 begin 3 repeat 4 Erzeuge e i n e z u f a e l l i g e Permutation von queen [ 1 ] zu queen [ n ] ; 5 Berechne d i e Arrays d 1, d 2 mit der 6 Anzahl der K o l l i s i o n e n auf den Diagonalen ; 7 f o r a l l i, j : i s t queen [ i ] oder queen [ j ] schlagbar, do 8 i f swap ( queen [ i ], queen [ j ] ) r e d u z i e r t K o l l i s i o n e n 9 then tausche ( queen [ i ], queen [ j ] ) ; 10 until keine K o l l i s i o n e n ; 11 end ; Zu beginn wird eine zufällige Permutation generiert. Diese erste Permutation wird i.a. zu Kollisionen auf den Diagonalen führen. Um die Anzahl der Kollisionen zu zählen, kann man wie folgt vorgehen: Sei i ein Zeilenindex und j ein Spaltenindex. Auf der negativen Diagonalen ist die Summe von Spalten- und Zeilenindex konstant, auf der positiven Diagonalen die Differenz. Dazu ein Beispiel: 4 4+1 3 3+2 (3-4) 2 2+3 (2-3) 1 (1-2) 1+4 1 2 3 4 Um also festzustellen, ob eine Dame auf der negativen Diagonalen der Position (i, j) steht, so muss man für k {1,..., n} nur überprüfen ob π(k) + k = i + j gilt und analog mit der Differenz für die positive Diagonale. 2
Für das n-damen Problem existieren 2n 1 negative Diagonalen und 2n 1 positive Diagonalen. Seien d 1 und d 2 zwei Arrays der Größe 2n 1, in der wir die Anzahl der Kollisionen auf den negativen bzw. positiven Diagonalen eintragen. Sind auf der m-ten negativen Diagonalen k Damen, so sind dort k 1 Kollisionen und es ist d 1 [m] = k 1. Der Algorithmus benutzt eine Gradienten Basierte Heuristik, er tauscht zwei Damen nur, wenn sich die Anzahl der Kollisionen verringert. Man muss also die Richtung des Gradienten bestimmen, die vorgibt, wann die Kollisionen reduziert werden. Die Idee ist ziemlich einfach, man errechnet die Anzahl der Kollisionen vor und nach einem Tausch, und tauscht nur, wenn diese Anzahl nach dem Tausch geringer ist als vorher. 1 repeat 2 tauschanzahl := 0 ; 3 for i in [ 1.. n ] do 4 for i in [ 1.. n ] do 5 i f queen [ i ] wird a t t a c k i e r t oder queen [ j ] wird a t t a c k i e r t 6 then 7 i f tausch ( queen [ i ], queen [ j ] ) v e r r i n g e r t K o l l i s i o n e n 8 then 9 begin 10 tausche ( queen [ i ], queen [ j ] ) ; 11 tauschanzahl := tauschanzahl + 1 ; 12 end ; 13 until tauschanzahl = 0 ; Diese Heuristik wird auf jedes Paar von Damen aus unserer ursprünglichen Permutation angewendet. Hat man am Ende keine Kollisionen mehr, so ist eine Lösung gefunden. Findet man nach allen möglichen Tauschoperationen keine Lösung, so wird eine neue Permutation generiert und der Algorithmus nochmal ausgeführt. Eine Dame kann maximal zwei Diagonalen beeinflussen (die positive und negative Diagonale, auf der sie steht), damit werden maximal zwei Werte in den Arrays d 1 und d 2 beeinflusst, nämlich die Diagonalen i + π(i) und i π(i). Ein Tausch von zwei Damen beeinflusst also maximal 8 Diagonalen. Man muss dazu erstmal die jeweils zwei Diagonalen untersuchen, die zu den Damen in ihrer ursprünglichen Position gehören und die jeweils zwei Diagonalen, die zu den Damen in ihrer neuen Position gehören. Damit ist die Anzahl der Operationen, die zu einer Tauschoperation gehört, konstant und unabhängig von dem n. Nun etwas zur Laufzeit des Algorithmus: Die zufällige Permutation kann in linearer Zeit in Abhänigkeit von n generiert werden. Unabhängig von n kann der Vergleich und Tausch (Zeile 5-9) in konstanter Zeit erfolgen. 3
Damit legt die Anzahl der Vergleiche und Tauschoperationen die Laufzeit des Algorithmus fest. Im worst case, werden in jeder Ausführung der repeat-schleife O(n 2 ) Vergleiche ausgeführt, da dort zwei for-schleifen sind. Jede Ausführung der repeat-schleife muss einen Tausch ausgeführt, d.h. die Anzahl der Kollisionen verringert haben. Für eine Dame ist die maximale Anzahl der Damen auf seinen Diagonalen n 1, also hat man nach spätestens n 1 Schritten keine Kollision mehr für jede Dame. Dadurch ist eine obere Schranke der Laufzeit des Algorithmus durch O(n 3 ) gegeben. Wird keine Lösung gefunden, d.h. obwohl keine Tauschoperationen mehr ausgeführt wurden, existiert immer noch eine Kollision, so wird eine neue Permutation generiert und der Algorithmus mit dieser ausgeführt. In der Praxis ist die Anzahl der benötigten Permutationen aber gering. Mit größer werdendem n geht die Anzahl der benötigten Permutationen gegen 1, d.h. für große n reicht eine Permutation um eine Lösung zu finden. Experimente in den letzten Jahren ergeben, dass die Laufzeit des Algorithmus in der Praxis ungefähr O(n log n) ist. 4
4 Statistiken Im folgenden werden wir nun noch einige Beobachtungen zusammentragen. Wir werden folgende experimentell erschlossene Daten zusammenfassen: Reale Laufzeit des Algorithmus Anzahl von Kollisionen erzeugt durch eine zufällige Permutation Die maximale Anzahl von Damen auf der gleichen Diagonalen in einer zufälligen Permutation Das probabilistische Verhalten des Algorithmus 1. Reale Laufzeit des Algorithmus Die reale Laufzeit von unserem Suchalgorithmus, programmiert in C und gemessen auf einem NeXT Personal Computer (mit einem 25 MHz Motorola 68030 Prozessor), ist in Tabelle 1 dargestellt. Da unser Algorithmus polynomielle Laufzeit hat, ist er unvergleichbar schneller als die meisten aktuellen KI Such-Algorithmen, die alle exponentielle Laufzeit haben. Durch die Speicherbegrenzung auf unserem Computer, war das größtmögliche lösbare Problem bei 500000 Damen. 2. Anzahl der Kollisionen in einer zufälligen Permutation In Tabelle 2 wir die durchschnittliche Anzahl von Kollisionen in einer zufälligen Permutation aufgezeigt. Dies gibt gerade die maximal notwendige Anzahl von Tauschoperationen an, um eine Lösung zu finden. Die Ergebnisse in dieser Tabelle basieren auf einem Durchschnitt von 100 zufälligen Permutationen. Theoretisch sind nicht mehr als n 1 Kollisionen auf einem n n Brett möglich, dieser Fall tritt bei allen Damen auf einer Diagonalen ein. Damit wird die Anzahl der Kollisionen sicherlich höchstens linear in n steigen. Man sieht jedoch nach einer Vielzahl von Ausführungen des Algorithmus, dass das Verhältnis zwischen der Anzahl der Kollisionen in einer zufälligen Permutation und der Brettgröße n gegen 0, 5285 geht wenn man mit n gegen 500.000 geht. 3. Die maximale Anzahl von Damen auf einer Diagonalen In Tabelle 3 wird die maximale Anzahl der Damen auf einer Diagonalen in einer zufälligen Permutation analysiert. Es wurden 100 zufällige Permutationen für jede Brettgröße generiert und jeweils die minimale und maximale Anzahl der Damen auf einer Diagonalen aufgezeichnet. Diese beiden Werte sind sehr nah beieinander. Die Kollisionen zwischen Damen auf einer Diagonalen sind relativ gleichmäßig verteilt. 4. Das proba- 5
bilistische Verhalten des Algorithmus Die folgenden beiden Tabellen 4 und 5 wurden durch 10 Beispielläufe des Algorithmus erhalten. Diese Tabelle zeigt das probabilistische Verhalten des Algorithmus für eine erfolgreiche Lösung aus der ersten zufälligen Permutation. Dabei wurde die Anzahl der Beispielläufe notiert, in denen aus der ersten zufälligen Permutation schon eine Lösung gefunden werden konnte. Zusätzlich wurde die maximale Anzahl von benötigten Permutationen zum Finden einer Lösung aufgezeichnet. Man sieht, dass die Anzahl der benötigten Permutation für größere n fällt. In unseren Problemgrößen und Beispielläufen findet der Algorithmus für n > 10.000 immer eine Lösung mit der ersten Permutation. Diese Tablle zeigt die Teile des Programms auf, in denen die meiste Zeit verbracht wird. Dabei wurden die Anzahl der Vergleiche und die Anzahl der Tauschoperationen aufgezeichnet. 5 Zusammenfassung Insgesamt liefert der Algorithmus eine Methode, die in der Praxis brauchbare Ergebnisse liefert, d.h. das n-damen Problem auch für große Instanzen in polynomieller Zeit löst. Jedoch ist theoretisch weiterhin eine exponientielle worst-case Laufzeit möglich, da nicht klar ist, wieviele Startpermutationen man braucht. Die Tabellen deuten zwar auf ein durchschnittlich sehr schnelles Verhalten des Algorithmus hin, jedoch wurde der Durchschnitt von nur 10 Durchläufen berechnet, was eine sehr kleine Instanz ist. 6
6 Anhang Tabelle 1: Algorithmus auf einer NeXT Maschine mit 25MHz Motorola 68030 Prozessor (10 Durchläufe; Zeiteinheit: Sekunden) Zeit des 1. Durchlaufs < 0,1 0,4 2,1 27,7 1.098,4 7.500 Zeit des 2. Durchlaufs < 0,1 0,2 1,9 38,2 1.081,2 9.065 Zeit des 3. Durchlaufs < 0,1 < 0,1 1,8 42,6 997,6 12.617 Zeit des 4. Durchlaufs < 0,1 < 0,1 3,1 34,9 979,9 11.730 Zeit des 5. Durchlaufs < 0,1 < 0,1 1,9 34,3 1.286,4 9934 Zeit des 6. Durchlaufs < 0,1 < 0,1 2,4 31,2 992,3 9.198 Zeit des 7. Durchlaufs < 0,1 0,2 1,9 41,2 1.425,5 9.789 Zeit des 8. Durchlaufs < 0,1 0,3 3,3 36,5 1.235,4 11.142 Zeit des 9. Durchlaufs < 0,1 0,1 2,3 52,4 1.285,7 11.788 Zeit des 10. Durchlaufs < 0,1 < 0,1 2,1 35,1 1285,4 8.300 Durchsch. Zeit zum F. einer Lösung < 0,1 0,1 2,3 37 1.167 10.106 Tabelle 2: Anzahl der Kollisionen in einer zufälligen Permutation (Durchschnitt von 100 Permutationen) Anzahl der Kollisionen /n 0,486 0,523 0,5277 0,5283 0,528694 0,528511 Tabelle 3: Maximale und minimale Anzahl von Damen auf der Diagonalen mit den meisten Damen in einer zufälligen Permutation (Durchschnitt von 100 Permutationen) Minimum 2 5 7 7 9 10 Maximum 5 7 7 9 9 10 7
Tabelle 4: Statistik über die Anzahl der benötigten Permutation (Durchschnitt von 10 Durchläufen) Lösungen in der ersten Permutation 2 6 8 10 10 10 Max. Anzahl von Permutationen 10 3 2 1 1 1 Tabelle 5: Statistik über die durchgeführten Operationen (Durchschnitt von 10 Durchläufen) Anzahl der Vergleiche 353 13.525 253.671 4.827.973 110.186.345 967.924.234 Anzahl der Tauschop. 198 2.385 15.116 166.215 2.034.907 11.447.508 8