Was ist das Damenproblem ?
Bei dem Damenproblem handelt es sich um ein Mathematisches Problem, dass auf den bestehenden Schachregeln beruht.
Gegeben ist ein quadratisches Schachfeld, welches mindestens n > 3
Felder groß sein muss. Auf diesem wird nun in jeder Spalte eine Dame platziert. Diese Damen dürfen sich aber nicht gegenseitig mit den bekannten Schachregeln schlagen dürfen, sondern müssen so angeordnet sein, dass sie sich gegenseitig nicht bedrohen. Für jede Anzahl an Felder gibt es dabei mindestens eine Lösung.
Im obigen Bild ist eine mögliche Lösung für das Damenproblem zu erkennen.
Lösung im Pseudocode
Das Vorgehen, um eine Lösung zu finden könnte folgendermaßen aussehen:
function backtrack {
BETRACHTE Moeglichkeiten Zeile
WENN 0 Moeglichkeiten
DANN GIB keine Loesung zurueck
SONST
FÜR jede moeglichkeit
SETZE Dame auf moeglichkeit
backtrack fuer naechste Zeile
WENN Loesung gefunden
GIB Loesung zurueck
}
Die oben abgebildete Lösung habe ich mit Simon erarbeitet. Ähnlichkeiten könne also vorkommen.
Bei diesem Vorgehen wird jede Möglichkeit, eine Dame zu platzieren, betrachtet. Sollte es jedoch keine Möglichkeit geben, auf die eine Dame gesetzt werden kann, so bricht man ab, und führt das ganze eine Zeile vorher aus. Andernfalls wird jede gefundene Möglichkeit getestet. Dabei wird die Dame auf die jeweilige Möglichkeit gesetzt und für die nächste Zeile wird die Funktion rekursiv aufgerufen, sodass man die Anzahl der Lösungen für die weiteren Zeilen weiß. Anhand dieses Ergebnisses, kann nun festgestellt werden, ob man die Dame auf ein nächstes Feld setzen muss, oder die Lösung gefunden hat.
Backtracking
Wie oben schon angedeut, ist das Problem mit Backtracking gelößt worden.
function Backtrack
Suche Lösung
wenn Lösung gefunden
führe Backtracking für nächste Zeile
Sonst
führe Backtracking für letzte Zeile durch
Am einfachsten ist es, sich dieses Verfahren an einem Baumdiagramm vorzustellen: Jeder Ast stellt eine Lösung dar. Dabei gehen wir solange einen Ast entlang, bis keine Lösung mehr gefunden werden kann. Ist dies der Fall, so gehen wir zurück bis zum letzten Knoten und gehen den nächsten Ast entlang.
Implementierung
Nachdem eine Dame gesetzt wurde, muss für alle Felder, die diese Dame bedroht, auch die Bedrohung um 1
erhöht werden.
x
und y
sind dabei die Position, auf die die Dame gesetzt wurde. Zusätzlich gibt delta
an, ob eine Bedrohung hinzukommt, oder ob eine weggenommen wurde. Würde also eine Dame gesetzt werden, so würde delta = 1
sein, weil delta bei jedem Feld auf die vorhandenen Bedrohungen addiert wird.
Das Vorgehen bei dieser Methode ist, dass man sich ein Quadrat vorstellt, welches nach jedem Durchlauf der for-Schleife
sich um 1
vergrößert. Dabei bleibt die Anzahl der zu ändernden Felder gleich, unabhängig von der Größe des Quadrates. Damit hat man dann alle Felder abgedeckt, die durch die Dame bedroht werden. (Waagerecht und Diagonal)
Alle Möglichkeiten werden in einem Array vom Typ Pos
gespeichert. Diese werden durch die Methdode getMoeglichkeiten()
für jede Reihe berechnet. Dannach wird die Dame auf eine Möglichkeit gesetzt. Für die nächste Reihe wird dann die Methode backtrack()
rekursiv aufgerufen. Dabei kann dann festgestellt werden, ob für die Position der Dame eine Lösung gefunden werden kann. Sollte also eine Lösung gefunden worden sein, so kann mit return
die for-Schleife
abgebrochen werden. Andernfalls setzte man die Dame auf die nächste Lösung. Am Ende ist die for-Schleife
komplett über alle Positionen iteriert und die Methode gibt null
zurück, da keine Lösung gefunden wurde.
Alle Lösungen finden
Weiterhin besteht die Möglichkeit, dass man alle Möglichkeiten für n
zurückgibt:
backtrack_all()
FALLS die Anzahl der Damen n ist
Speichere die Position der Damen
GIB keine Lösung zurück
finde die erste Spalte ohne Dame
DURCHLAUFE ALLE Felder dieser Spalte
FALLS das Feld unbedroht ist
setze eine Dame auf das Feld
backtrack_all()
entferne die Dame wieder vom Feld
GIB keine Lösung zurück