Latar Belakang
Matriks Hankel biner adalah matriks dengan kemiringan diagonal konstan (diagonal miring positif) yang hanya mengandung 0
s dan 1
s. Contohnya matriks Hankel biner 5x5 terlihat seperti
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
mana a, b, c, d, e, f, g, h, i
yang baik 0
atau 1
.
Mari kita mendefinisikan matriks M sebagai Hankelable jika ada permutasi urutan baris dan kolom M sehingga M adalah matriks Hankel. Ini berarti seseorang dapat menerapkan satu permutasi pada urutan baris dan yang mungkin berbeda pada kolom.
Tantangan
Tantangannya adalah untuk menghitung berapa banyak Hankelable n
dengan n
matriks yang ada untuk semua n
hingga nilai sebesar mungkin.
Keluaran
Untuk setiap bilangan bulat n dari 1 ke atas, output jumlah Hankelable n
dengan n
matriks dengan entri yang 0
atau 1
.
Untuk n = 1,2,3,4,5
jawabannya harus 2,12,230,12076,1446672
. (Terima kasih kepada orlp untuk kode untuk menghasilkan ini.)
Batas waktu
Saya akan menjalankan kode Anda di mesin saya dan menghentikannya setelah 1 menit. Kode yang menampilkan jawaban yang benar hingga nilai n menang terbesar. Batas waktu adalah untuk semuanya, mulai n = 1
dari nilai terbesar n
yang Anda berikan jawabannya.
Pemenang akan menjadi jawaban terbaik pada akhir Sabtu 18 April.
Tie Breaker
Dalam kasus dasi untuk beberapa maksimum n
saya akan menghitung berapa lama waktu yang dibutuhkan untuk memberikan hasil n+1
dan yang tercepat menang. Jika mereka berjalan dalam waktu yang sama hingga dalam satu detik hingga n+1
, pengiriman pertama menang.
Bahasa dan perpustakaan
Anda dapat menggunakan bahasa apa pun yang memiliki kompiler / juru bahasa / dll yang tersedia secara bebas. untuk Linux dan semua perpustakaan yang juga tersedia secara bebas untuk Linux.
Mesin saya
Pengaturan waktu akan dijalankan di mesin saya. Ini adalah instalasi ubuntu standar pada Prosesor Delapan Core AMD FX-8350 pada Motherboard Asus M5A78L-M / USB3 (Socket AM3 +, 8GB DDR3). Ini juga berarti saya harus dapat menjalankan kode Anda. Sebagai konsekuensinya, hanya gunakan perangkat lunak gratis yang mudah tersedia dan harap sertakan instruksi lengkap cara menyusun dan menjalankan kode Anda.
Catatan
Saya merekomendasikan untuk tidak mengulangi semua matriks demi matriks dan mencoba mendeteksi apakah masing-masing memiliki properti yang saya jelaskan. Pertama, ada terlalu banyak dan kedua, sepertinya tidak ada cara cepat untuk melakukan deteksi ini .
Entri terkemuka sejauh ini
- n = 8 oleh Peter Taylor. Jawa
- n = 5 oleh orlp. Python
sumber
n=6
totalnya adalah260357434
. Saya pikir tekanan memori adalah masalah yang lebih besar daripada waktu CPU.Jawaban:
Java (n = 8)
Simpan sebagai
HankelCombinatorics.java
, kompilasi sebagaijavac HankelCombinatorics.java
, jalankan sebagaijava -Xmx2G HankelCombinatorics
.Dengan
NUM_THREADS = 4
mesin quad-core saya mendapat20420819767436
untukn=8
di 50 sampai dengan 55 detik berlalu, dengan jumlah wajar variabilitas antara berjalan; Saya berharap bahwa itu harus dengan mudah mengelola hal yang sama pada mesin octa-core Anda tetapi akan memakan waktu satu jam atau lebih untuk mendapatkannyan=9
.Bagaimana itu bekerja
Mengingat
n
, ada matriks2^(2n-1)
binern
xn
Hankel. Baris dapat di permutasi dengann!
cara, dan kolom dengann!
cara. Yang perlu kita lakukan adalah menghindari penghitungan ganda ...Jika Anda menghitung jumlah setiap baris, maka permutasi baris atau permutasi kolom tidak mengubah multiset jumlah. Misalnya
memiliki jumlah baris multiset
{3, 3, 2, 2, 2}
, dan demikian pula semua matriks Hankelable berasal darinya. Ini berarti bahwa kita dapat mengelompokkan matriks Hankel dengan multiset jumlah baris ini dan kemudian menangani setiap grup secara independen, mengeksploitasi beberapa inti prosesor.Ada juga simetri yang dapat dieksploitasi: matriks dengan nol lebih banyak daripada yang ada di bijih dengan matriks dengan lebih banyak dari nol.
Penghitungan ganda terjadi ketika Hankel matriks
M_1
dengan baris permutasir_1
dan kolom permutasic_1
cocok Hankel matriksM_2
dengan baris permutasir_2
dan kolom permutasic_2
(sampai dengan dua tapi tidak semua tigaM_1 = M_2
,r_1 = r_2
,c_1 = c_2
). Baris dan kolom permutasi independen, jadi jika kita menerapkan baris permutasir_1
untukM_1
dan baris permutasir_2
untukM_2
, kolom sebagai multisets harus sama. Jadi untuk setiap grup, saya menghitung semua multiset kolom yang diperoleh dengan menerapkan permutasi baris ke matriks dalam grup. Cara mudah untuk mendapatkan representasi kanonik dari multiset adalah dengan menyortir kolom, dan itu juga berguna pada langkah berikutnya.Setelah memperoleh multiset kolom yang berbeda, kita perlu menemukan berapa banyak
n!
permutasi dari masing-masing yang unik. Pada titik ini, penghitungan ganda hanya dapat terjadi jika multiset kolom yang diberikan memiliki kolom duplikat: apa yang perlu kita lakukan adalah menghitung jumlah kemunculan setiap kolom yang berbeda dalam multiset dan kemudian menghitung koefisien multinomial yang sesuai. Karena kolom diurutkan, mudah untuk menghitung.Akhirnya kami menambahkan semuanya.
Kompleksitas asimptotik bukanlah hal sepele untuk dihitung dengan presisi penuh, karena kita perlu membuat beberapa asumsi tentang perangkat. Kami mengevaluasi urutan
2^(2n-2) n!
multiset kolom, meluangkann^2 ln n
waktu untuk masing-masing (termasuk penyortiran); jika pengelompokan tidak mengambil lebih dari satuln n
faktor, kami memiliki kompleksitas waktuTheta(4^n n! n^2 ln n)
. Tetapi karena faktor eksponensial sepenuhnya mendominasi faktor polinomial, maka faktor ituTheta(4^n n!) = Theta((4n/e)^n)
.sumber
Python2 / 3
Pendekatan yang cukup naif, dalam bahasa yang lambat:
Jalankan dengan mengetik
python script.py
.sumber
from __future__ import print_function
(atau sesuatu seperti itu)?return(1)
. Sekarang gantireturn
denganprint
:)Haskell
Tidak ada yang secepat Peter - itu pengaturan yang cukup mengesankan dia sampai di sana! Sekarang dengan lebih banyak kode yang disalin dari internet. Pemakaian:
sumber