Hintergrund
Eine binäre Hankel-Matrix ist eine Matrix mit konstanten Schrägdiagonalen (positiv abfallenden Diagonalen), die nur 0
s und 1
s enthält. ZB sieht eine 5x5 binäre Hankelmatrix so aus
a b c d e
b c d e f
c d e f g
d e f g h
e f g h i
wo a, b, c, d, e, f, g, h, i
sind entweder 0
oder 1
.
Definieren wir eine Matrix M als Hankelbar, wenn es eine Permutation der Reihenfolge der Zeilen und Spalten von M gibt, so dass M eine Hankel-Matrix ist. Dies bedeutet, dass man eine Permutation auf die Reihenfolge der Zeilen und eine möglicherweise andere auf die Spalten anwenden kann.
Die Herausforderung
Die Herausforderung besteht darin , zu zählen , wie viele Hankelable n
von n
Matrizen für alle da sindn
bis zu so großen Wert wie möglich.
Ausgabe
Geben Sie für jede ganze Zahl n ab 1 die Anzahl der Hankelablen
von n
Matrizen mit Einträgen aus, die 0
oder sind 1
.
Dafür sollten n = 1,2,3,4,5
die Antworten sein2,12,230,12076,1446672
. (Danke an orlp für den Code, der diese erstellt hat.)
Zeitlimit
Ich werde Ihren Code auf meinem Computer ausführen und ihn nach 1 Minute stoppen. Der Code, der die richtigen Antworten bis zum größten Wert von n ausgibt, gewinnt. Die Frist ist für alles von n = 1
bis zum größten Wert vonn
auf den Sie eine Antwort geben.
Der Gewinner wird die beste Antwort bis Ende Samstag, den 18. April sein.
Kabelbinder
Bei einem Unentschieden n
werde ich mal sehen, wie lange es dauert, bis die Ausgänge erreicht sind n+1
und der Schnellste gewinnt. In dem Fall, dass sie in der gleichen Zeit innerhalb einer Sekunde bis zu laufenn+1
, gewinnt die erste Einreichung.
Sprachen und Bibliotheken
Sie können jede Sprache verwenden, die über einen frei verfügbaren Compiler / Interpreter / etc. Verfügt. für Linux und alle Bibliotheken, die auch für Linux frei verfügbar sind.
Meine Maschine
Die Timings werden auf meinem Computer ausgeführt. Dies ist eine Ubuntu-Standardinstallation auf einem AMD FX-8350-Prozessor mit acht Kernen auf einem Asus M5A78L-M / USB3-Motherboard (Sockel AM3 +, 8 GB DDR3). Dies bedeutet auch, dass ich in der Lage sein muss, Ihren Code auszuführen. Verwenden Sie daher nur leicht verfügbare kostenlose Software und fügen Sie vollständige Anweisungen zum Kompilieren und Ausführen Ihres Codes bei.
Anmerkungen
Ich empfehle, nicht alle n-mal-n-Matrizen zu iterieren und zu ermitteln, ob jede die von mir beschriebene Eigenschaft hat. Erstens gibt es zu viele und zweitens scheint es keine schnelle Möglichkeit zu geben, diese Erkennung durchzuführen .
Bisher führende Einträge
- n = 8 von Peter Taylor. Java
- n = 5 von orlp. Python
quelle
n=6
die Summe ist260357434
. Ich denke, der Speicherdruck ist ein größeres Problem als die CPU-Zeit.Antworten:
Java (n = 8)
Speichern als
HankelCombinatorics.java
, Kompilieren alsjavac HankelCombinatorics.java
, Ausführen alsjava -Xmx2G HankelCombinatorics
.Mit
NUM_THREADS = 4
auf meiner Quad-Core - Maschine wird es20420819767436
fürn=8
in 50 bis 55 Sekunden verstrichen, mit einem fairen Betrag von Variabilität zwischen den Läufen; Ich gehe davon aus, dass es auf Ihrem Octa-Core-Computer problemlos funktioniert, aber es dauert mindestens eine Stunde, bis es verfügbar istn=9
.Wie es funktioniert
Vorausgesetzt
n
, es gibt2^(2n-1)
binären
xn
Hankel-Matrizen. Die Zeilen können auf verschiedenen!
Arten und die Spalten auf verschiedenen!
Arten permutiert werden. Alles was wir tun müssen, ist Doppelzählungen zu vermeiden ...Wenn Sie die Summe jeder Zeile berechnen, ändert weder das Permutieren der Zeilen noch das Permutieren der Spalten die Summenmehrfachmenge. Z.B
hat Zeilensummen-Multiset
{3, 3, 2, 2, 2}
und alle daraus abgeleiteten Hankelable-Matrizen. Dies bedeutet, dass wir die Hankel-Matrizen nach diesen Zeilensummen-Multisätzen gruppieren und dann jede Gruppe unabhängig behandeln können, wobei mehrere Prozessorkerne ausgenutzt werden.Es gibt auch eine ausnutzbare Symmetrie: Die Matrizen mit mehr Nullen als Einsen stehen im Widerspruch zu den Matrizen mit mehr Einsen als Nullen.
Doppelzählung auftritt , wenn Hankel - Matrix
M_1
mit Zeilen Permutationr_1
und Spaltenpermutationc_1
einstimmt Hankel - MatrixM_2
mit Zeilen Permutationr_2
und Spaltenpermutationc_2
(mit bis zu zwei , aber nicht alle drei vonM_1 = M_2
,r_1 = r_2
,c_1 = c_2
). Die Zeilen- und Spaltenpermutationen sind unabhängig. Wenn Sie also die Zeilenpermutationr_1
aufM_1
und die Zeilenpermutationr_2
auf anwendenM_2
, müssen die Spalten als Multisets gleich sein. Daher berechne ich für jede Gruppe alle Spalten-Multisets, die durch Anwenden einer Zeilenpermutation auf eine Matrix in der Gruppe erhalten werden. Der einfache Weg, eine kanonische Darstellung der Multisets zu erhalten, besteht darin, die Spalten zu sortieren. Dies ist auch im nächsten Schritt nützlich.Nachdem wir die verschiedenen Spalten-Multisets erhalten haben, müssen wir herausfinden, wie viele der
n!
Permutationen von jeder einzigartig sind. Zu diesem Zeitpunkt kann eine Doppelzählung nur stattfinden, wenn ein gegebenes Spalten-Multiset doppelte Spalten enthält. Wir müssen lediglich die Anzahl der Vorkommen jeder einzelnen Spalte im Multiset zählen und dann den entsprechenden Multinomialkoeffizienten berechnen. Da die Spalten sortiert sind, ist es einfach, sie zu zählen.Schließlich addieren wir sie alle.
Die asymptotische Komplexität ist nicht einfach mit voller Genauigkeit zu berechnen, da wir einige Annahmen über die Mengen treffen müssen. Wir bewerten die Reihenfolge der
2^(2n-2) n!
Spalten-Multisets, wobei wir uns jeweilsn^2 ln n
Zeit nehmen (einschließlich der Sortierung). Wenn die Gruppierung nicht mehr als einenln n
Faktor ausmacht, haben wir zeitliche KomplexitätTheta(4^n n! n^2 ln n)
. Aber da die Exponentialfaktoren die Polynomfaktoren vollständig dominieren, ist dies der FallTheta(4^n n!) = Theta((4n/e)^n)
.quelle
Python2 / 3
Ziemlich naiver Ansatz in einer langsamen Sprache:
Führen Sie durch Eingabe
python script.py
.quelle
from __future__ import print_function
(oder so etwas) nicht?return(1)
. Jetzt ersetzenreturn
durchprint
:)Haskell
Nirgendwo so schnell wie bei Peter - das ist ein ziemlich beeindruckendes Setup, das er dort hat! Jetzt mit viel mehr Code aus dem Internet kopiert. Verwendung:
quelle