Finden Sie bei einer ganzen Zahl 2n die Anzahl der Möglichkeiten, wie 2n ^ 2 schwarze Bauern und 2n ^ 2 weiße Bauern auf einem 2n x 2n-Schachbrett so angeordnet werden können, dass kein Bauer einen anderen angreift.
- Ein schwarzer Bauer kann nur einen weißen Bauern angreifen und umgekehrt.
- Es folgen die üblichen Schachregeln für Angriffe, dh weiße Bauern greifen Felder unmittelbar diagonal vorne an und die schwarzen Bauern greifen Felder unmittelbar diagonal rückwärts an (vom weißen Beobachter aus gesehen).
- Alle Rotationen und Reflexionen gelten als unterschiedlich.
Das Programm, das alle möglichen Konfigurationen für den höchsten Wert von 2n in 120 Sekunden ausgeben kann, gewinnt. (Alle Programme sind jedoch willkommen)
Zum Beispiel kann Alices Programm innerhalb von 120 Sekunden bis zu n = 16 verarbeiten, während Bobs innerhalb derselben Zeit bis zu n = 20 verarbeiten kann. Bob gewinnt.
Plattform: Linux 2.7GHz @ 4 CPUs
fastest-code
combinatorics
chess
Agnishom Chattopadhyay
quelle
quelle
2n^2
Bauern sagen , ist das(2n)^2
oder2(n^2)
?Antworten:
Java, n = 87 auf meinem Computer
Das Ergebnis für n = 87 ist
Dies verwendet derzeit ein dynamisches Programmierschema, das O (n ^ 4) -Operationen verwendet, um die Möglichkeiten zum Platzieren von
p
Bauern auf den Quadraten einer Farbe für zu berechnen0 <= p <= n^2
. Ich denke, es sollte möglich sein, dies viel effizienter zu tun.Überprüfen Sie die Ergebnisse hier.
Erläuterung
In einer gültigen Lösung müssen die untersten weißen Bauern in jeder Spalte eine Zick-Zack-Linie wie folgt bilden:
Das heißt, die Höhe der Linie in Spalte c muss +/- 1 von ihrer Position in Spalte c - 1 betragen . Die Linie kann auch auf zwei imaginäre Reihen über der Oberseite der Tafel verlaufen.
Wir können die dynamische Programmierung verwenden, um die Anzahl der Möglichkeiten zum Zeichnen einer Linie in den ersten c- Spalten zu ermitteln, die p Bauern in diesen Spalten enthält. Sie befindet sich in der Höhe h in der c- ten Spalte und verwendet die Ergebnisse für Spalte c - 1 , Höhe h + / - 1 und Anzahl der Bauern p - h .
quelle
Java
Derzeit ist mein Code sehr lang und langweilig. Ich arbeite daran, ihn schneller zu machen. Ich benutze eine rekursive Methode, um die Werte zu finden. Es berechnet die ersten 5 innerhalb von 2 oder 3 Sekunden, wird danach aber viel langsamer. Ich bin mir auch noch nicht sicher, ob die Zahlen stimmen, aber die ersten scheinen mit den Kommentaren übereinzustimmen. Anregungen sind willkommen.
Ausgabe
Erläuterung
Die Grundidee ist Rekursion. Im Wesentlichen beginnen Sie mit einer leeren Tafel, einer Tafel mit allen Nullen. Die rekursive Methode prüft nur, ob sie einen schwarzen oder weißen Bauern an die nächste Position bringen kann. Wenn sie nur eine Farbe setzen kann, setzt sie sie dort ab und ruft sich selbst auf. Wenn es beide Farben setzen kann, nennt es sich zweimal, eine mit jeder Farbe. Jedes Mal, wenn es sich selbst nennt, werden die verbleibenden Quadrate und die entsprechende verbleibende Farbe verringert. Wenn es das gesamte Brett gefüllt hat, gibt es die aktuelle Anzahl + 1 zurück. Wenn es herausfindet, dass es keine Möglichkeit gibt, einen schwarzen oder weißen Bauern an die nächste Position zu bringen, gibt es 0 zurück, was bedeutet, dass es ein toter Pfad ist.
Code
Probieren Sie es hier aus (Läuft für Ideone nicht schnell genug, sodass der letzte Wert nicht gedruckt wird. Meine Lösung scheint nicht sehr gut zu sein!)
quelle
C ++ mit pthreads, n =
147156Das neueste Ergebnis ist das Ausführen des gleichen Codes wie zuvor auf einem kräftigeren Computer. Dies wurde nun auf einem Desktop mit einem Quad-Core i7 (Core i7-4770) ausgeführt, der in 120 Sekunden auf n = 156 kam. Das Ergebnis ist:
Dies verwendet einen dynamischen Programmieralgorithmus. Ich dachte anfangs über Ansätze nach, bei denen das Ergebnis Zeile für Zeile erstellt werden würde, aber ich konnte nie einen Weg finden, die Lösung zu erweitern, ohne eine Menge Status zu verfolgen.
Die wichtigsten Erkenntnisse, die eine einigermaßen effiziente Lösung ermöglichten, waren:
Wenn Sie sich eine Diagonale einer gültigen Konfiguration ansehen, besteht diese immer aus einer Folge von schwarzen Bauern, gefolgt von einer Folge von weißen Bauern (wobei jede Folge auch leer sein kann). Mit anderen Worten, jede Diagonale kann vollständig durch ihre Anzahl schwarzer Bauern charakterisiert werden.
Daher ist der für jede Diagonale verfolgte Zustand die Anzahl der gültigen Bauernkonfigurationen für jede Kombination von:
Beim Übergang von einer Diagonale zur nächsten gibt es eine weitere Einschränkung, um gültige Lösungen zu erstellen: Die Position, die schwarze Bauern von weißen Bauern trennt, kann nicht erhöht werden. Die Anzahl der gültigen Konfigurationen wird also als die Summe der gültigen Konfigurationen der vorherigen Diagonale für Positionen berechnet, die gleich oder größer sind.
Der grundlegende DP-Schritt ist dann sehr einfach. Jeder Wert in einer Diagonale ist nur eine Summe von Werten aus der vorherigen Diagonale. Der einzige etwas schmerzhafte Teil ist die korrekte Berechnung der Indizes und Schleifenbereiche. Da wir an Diagonalen arbeiten, nimmt die Länge in der ersten Hälfte der Berechnung zu und in der zweiten Hälfte ab, was die Berechnung der Schleifenbereiche umständlicher macht. Es gibt auch einige Überlegungen zu den Werten an der Grenze der Platine, da sie nur diagonale Nachbarn auf einer Seite haben, wenn sie von diagonal zu diagonal wechseln.
Die verwendete Speichermenge beträgt O (n ^ 3). Ich behalte zwei Kopien der Statusdaten und Ping-Pong zwischen ihnen. Ich glaube, es wäre möglich, mit einer einzigen Instanz der Zustandsdaten zu arbeiten. Sie müssen jedoch sehr vorsichtig sein, dass keine Werte aktualisiert werden, bevor die alten Werte vollständig verbraucht sind. Außerdem würde es für die von mir eingeführte Parallelverarbeitung nicht gut funktionieren.
Die Komplexität der Laufzeit ist ... polynomisch. Der Algorithmus enthält 4 verschachtelte Schleifen, sodass er auf den ersten Blick wie O (n ^ 4) aussehen würde. Aber Sie brauchen offensichtlich Bigint bei diesen Größen, und die Zahlen selbst werden auch bei größeren Größen länger. Die Anzahl der Stellen im Ergebnis scheint ungefähr proportional zu n zuzunehmen, was das Ganze zu O (n ^ 5) machen würde. Auf der anderen Seite habe ich einige Leistungsverbesserungen festgestellt, die es vermeiden, den gesamten Bereich aller Schleifen zu durchlaufen.
Obwohl dies immer noch ein ziemlich teurer Algorithmus ist, geht er viel weiter als die Algorithmen, die Lösungen aufzählen, die alle exponentiell sind.
Einige Hinweise zur Implementierung:
Hauptalgorithmuscode.
THREADS
steuert die Anzahl der verwendeten Threads, wobei die Anzahl der CPU-Kerne ein vernünftiger Ausgangspunkt sein sollte:Dies erfordert auch eine Bigint-Klasse, die ich zu diesem Zweck geschrieben habe. Beachten Sie, dass dies keine Allzweck-Bigint-Klasse ist. Es reicht gerade aus, um die von diesem speziellen Algorithmus verwendeten Operationen zu unterstützen:
quelle
Fantom
Hier ist ein erster Beitrag, der das Framework einrichtet. Ich denke, das Verfahren ist relativ gut, aber die Implementierung im Moment ist irgendwie beschissen. Ich muss wahrscheinlich versuchen, die Anzahl der Berechnungen, die ich mache, zu minimieren und stattdessen einfach mehr Konstanten zu übergeben.
Strategie
Grundsätzlich muss jeder weiße Bauer andere weiße Bauern angreifen. Also beginne ich damit, einen weißen Bauern zu platzieren, Bauern an jeder Stelle zu platzieren, die er angreift, und im Wesentlichen das Brett mit allen Stellen zu füllen, an denen ein weißer Bauer gehen muss. Ich höre auf, wenn ich schon zu viele weiße Bauern hinzugefügt habe. Wenn ich am Ende genau 2n ^ 2 Bauern habe, ist das eine Lösung. Wenn weniger, füge irgendwo einen weiteren weißen Bauern hinzu, fülle alle erforderlichen Stellen aus und zähle erneut. Ich teile jedes Mal rekursiv auf, wenn eine Füllung mit weniger als 2n ^ 2 gefunden wird, und berechne die Anzahl der Lösungen mit und ohne den letzten Bauern, den ich hinzugefügt habe.
Code
Ausgabe
Schafft es momentan nur auf 5, aber ich denke, der größte Teil des Problems liegt in der Implementierung.
Prüfung
quelle