tło
Binarna macierz Hankela to macierz o stałych przekątnych (dodatnich ukośnych przekątnych) zawierająca tylko 0
s i 1
s. Np. Wygląda binarna macierz Hankela 5x5
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
gdzie a, b, c, d, e, f, g, h, i
są albo 0
albo 1
.
Zdefiniujmy macierz M jako Hankelable, jeśli istnieje permutacja rzędu rzędów i kolumn M, tak że M jest macierzą Hankela. Oznacza to, że można zastosować jedną permutację do kolejności wierszy i ewentualnie inną do kolumn.
Wyzwanie
Wyzwanie polega na policzeniu, ile jest Hankelable n
według n
macierzy dla wszystkich, n
aż do jak największej wartości.
Wynik
Dla każdej liczby całkowitej od 1 w górę, wypisz liczbę Hankelablen
według n
macierzy z wpisami, które są 0
lub 1
.
Na n = 1,2,3,4,5
odpowiedzi powinno być 2,12,230,12076,1446672
. (Dzięki orlp za kod do ich wytworzenia.)
Limit czasu
Uruchomię twój kod na moim komputerze i zatrzymam go po 1 minucie. Kod, który wyświetla poprawne odpowiedzi do największej wartości n, wygrywa. Limit czasu dotyczy wszystkiego, od n = 1
największej wartości, n
na którą dajesz odpowiedź.
Zwycięzca będzie najlepszą odpowiedzią do końca soboty 18 kwietnia.
Tie Breaker
W przypadku remisu na maksymalny n
czas określę, ile czasu zajmie oddanie wyników, n+1
a najszybszy wygra. W przypadku, gdy biegną one w tym samym czasie do sekundy n+1
, wygrywa pierwsze zgłoszenie.
Języki i biblioteki
Możesz używać dowolnego języka, który ma swobodnie dostępny kompilator / tłumacz / etc. dla systemu Linux i dowolnych bibliotek, które są również bezpłatnie dostępne dla systemu Linux.
Moja maszyna
Czasy będą uruchamiane na moim komputerze. Jest to standardowa instalacja ubuntu na ośmiordzeniowym procesorze AMD FX-8350 na płycie głównej Asus M5A78L-M / USB3 (Socket AM3 +, 8 GB DDR3). Oznacza to również, że muszę być w stanie uruchomić Twój kod. W związku z tym korzystaj tylko z łatwo dostępnego bezpłatnego oprogramowania i dołącz pełne instrukcje, jak skompilować i uruchomić kod.
Notatki
Odradzam iterację wszystkich macierzy n przez n i próbę wykrycia, czy każda z nich ma właściwość, którą opisuję. Po pierwsze, jest ich zbyt wiele, a po drugie, wydaje się, że nie ma szybkiego sposobu na wykrycie tego .
Dotychczasowe wpisy
- n = 8 autorstwa Petera Taylora. Jawa
- n = 5 przez orlp. Pyton
źródło
n=6
sumie jest260357434
. Myślę, że presja pamięci jest większym problemem niż czas procesora.Odpowiedzi:
Java (n = 8)
Zapisz jako
HankelCombinatorics.java
, skompiluj jakojavac HankelCombinatorics.java
, uruchom jakojava -Xmx2G HankelCombinatorics
.Z
NUM_THREADS = 4
moją czterordzeniową maszyną trwa to20420819767436
odn=8
50 do 55 sekund, z dużą zmiennością między seriami; Oczekuję, że powinno to łatwo zarządzać tym samym na twoim komputerze z ośmiordzeniowym rdzeniem, ale zajmie to godzinę lub dłużejn=9
.Jak to działa
Biorąc pod uwagę
n
, istnieją macierze2^(2n-1)
binarnen
xn
Hankela. Wiersze można permutować nan!
różne sposoby, a kolumny nan!
różne sposoby. Wszystko, co musimy zrobić, to uniknąć podwójnego liczenia ...Jeśli obliczysz sumę każdego wiersza, to ani permutacja wierszy, ani permutacja kolumn nie zmieni multiset sum. Na przykład
ma
{3, 3, 2, 2, 2}
multiset sumy wierszy , podobnie jak wszystkie macierze Hankelable z niego pochodzące. Oznacza to, że możemy pogrupować macierze Hankela według tych multisets sumy wierszy, a następnie obsługiwać każdą grupę niezależnie, wykorzystując wiele rdzeni procesora.Istnieje również użyteczna symetria: macierze z większą liczbą zer niż jedynki są wstrząsane z macierzami z większą liczbą zer niż zera.
Podwójnego zliczania występuje podczas Hankel matrycy
M_1
z rzędu permutacjir_1
i kolumnę permutacjic_1
odpowiada Hankel matrycęM_2
z rzędu permutacjir_2
i permutacji kolumnowejc_2
(w liczbie do dwóch, lecz nie wszystkich trzechM_1 = M_2
,r_1 = r_2
,c_1 = c_2
). Wiersz i kolumna permutacje są niezależne, więc jeśli zastosujemy wiersza permutacjir_1
doM_1
i wiersza permutacjir_2
doM_2
, kolumny jak multisets muszą być równe. Tak więc dla każdej grupy obliczam wszystkie wielokrotności kolumn uzyskane przez zastosowanie permutacji wiersza do macierzy w grupie. Prostym sposobem na uzyskanie kanonicznej reprezentacji multisets jest sortowanie kolumn, co jest również przydatne w następnym kroku.Po uzyskaniu odrębnych multisets kolumnowych musimy dowiedzieć się, ile
n!
kombinacji każdego z nich jest unikalnych. W tym momencie podwójne liczenie może wystąpić tylko wtedy, gdy dany multiset kolumny ma zduplikowane kolumny: musimy policzyć liczbę wystąpień każdej odrębnej kolumny w multisecie, a następnie obliczyć odpowiedni współczynnik wielomianowy. Ponieważ kolumny są posortowane, łatwo jest policzyć.Na koniec dodajemy je wszystkie.
Złożoność asymptotyczna nie jest łatwa do obliczenia z pełną precyzją, ponieważ musimy poczynić pewne założenia dotyczące zbiorów. Oceniamy według kolejności
2^(2n-2) n!
multisets kolumn, zabierającn^2 ln n
czas dla każdego (łącznie z sortowaniem); jeśli grupowanie nie zajmuje więcej niżln n
czynnik, mamy złożoność czasuTheta(4^n n! n^2 ln n)
. Ale ponieważ czynniki wykładnicze całkowicie dominują w przypadku wielomianów, tak właśnie jestTheta(4^n n!) = Theta((4n/e)^n)
.źródło
Python2 / 3
Dość naiwne podejście w wolnym języku:
Uruchom, wpisując
python script.py
.źródło
from __future__ import print_function
(czy coś takiego)?return(1)
. Teraz zastąpićreturn
zprint
:)Haskell
Nigdzie nie tak szybko jak u Petera - to imponująca konfiguracja, którą on tam ma! Teraz z większą ilością kodu skopiowanego z Internetu. Stosowanie:
źródło