Фон
Бинарная ганкелева матрица - это матрица с постоянными косыми диагоналями (положительными наклонными диагоналями), содержащая только 0
s и 1
s. Например, бинарная ганкелева матрица 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
где a, b, c, d, e, f, g, h, i
либо 0
или 1
.
Давайте определим матрицу M как ганкелеву, если есть перестановка порядка строк и столбцов M, так что M является ганкелевой матрицей. Это означает, что можно применить одну перестановку к порядку строк и, возможно, другую к столбцам.
Соревнование
Задача состоит в том, чтобы посчитать, сколько Hankelable n
по n
матрицам существует для всехn
до максимально возможного значения.
Выход
Для каждого целого числа n от 1 и выше выведите число Hankelable n
по n
матрицам с записями, которые являются 0
или 1
.
Для n = 1,2,3,4,5
ответов должны быть2,12,230,12076,1446672
. (Спасибо orlp за код для их создания.)
Лимит времени
Я запусту ваш код на моей машине и остановлю его через 1 минуту. Код, который выводит правильные ответы до наибольшего значения n побед. Ограничение по времени для всего от n = 1
самой большой стоимостиn
на которое вы даете ответ.
Победитель будет лучшим ответом к концу субботы 18 апреля.
Tie Breaker
В случае ничьей по максимуму n
я определю, сколько времени потребуется, чтобы довести результаты до максимума и выиграть n+1
самый быстрый. В случае, если они работают одновременно с точностью до секунды доn+1
, выигрывает первая заявка.
Языки и библиотеки
Вы можете использовать любой язык со свободно доступным компилятором / интерпретатором и т. Д. для Linux и любых библиотек, которые также свободно доступны для Linux.
Моя машина
Время будет работать на моей машине. Это стандартная установка Ubuntu на восьмиъядерный процессор AMD FX-8350 на материнской плате Asus M5A78L-M / USB3 (Socket AM3 +, 8 ГБ DDR3). Это также означает, что мне нужно иметь возможность запустить ваш код. Как следствие, используйте только легкодоступное бесплатное программное обеспечение и, пожалуйста, включите подробные инструкции по компиляции и запуску вашего кода.
Примечания
Я рекомендую не делать итерации по всем n по n матрицам и пытаться определить, обладает ли каждая из них свойством, которое я описываю. Во-первых, их слишком много, а во-вторых, кажется, нет быстрого способа сделать это обнаружение .
Ведущие записи пока
- n = 8 Питер Тейлор. Джава
- n = 5 по orlp. питон
источник
n=6
всего есть260357434
. Я думаю, что нехватка памяти является более важной проблемой, чем время процессора.Ответы:
Java (n = 8)
Сохранить как
HankelCombinatorics.java
, скомпилировать какjavac HankelCombinatorics.java
, запустить какjava -Xmx2G HankelCombinatorics
.На
NUM_THREADS = 4
моей четырехъядерной машине он длится20420819767436
отn=8
50 до 55 секунд, с достаточной вариативностью между запусками; Я ожидаю, что он легко справится с тем же на вашей восьмиъядерной машине, но потребуется час или больше, чтобы получитьn=9
.Как это устроено
Учитывая
n
, существуют2^(2n-1)
бинарныеn
хn
ганкелевы матрицы. Строки можно переставлятьn!
разными способами, а столбцы -n!
разными способами. Все, что нам нужно сделать, это избежать двойного счета ...Если вы вычисляете сумму каждой строки, то ни перестановка строк, ни перестановка столбцов не изменяют мультимножество сумм. Например
имеет многозначную сумму строк
{3, 3, 2, 2, 2}
, как и все матрицы Ханкеля, полученные из него. Это означает, что мы можем сгруппировать матрицы Ханкеля по этим мультимножествам суммы строк, а затем обрабатывать каждую группу независимо, используя несколько процессорных ядер.Существует также эксплуатируемая симметрия: матрицы с большим числом нулей, чем единицы, находятся в биекции с матрицами с большим числом нулей.
Двойной учет имеет место , когда Ганкель матрица
M_1
с перестановкой строкr_1
и перестановкой столбцовc_1
соответствует матрице ганкелеваM_2
с перестановкой строкr_2
и перестановкой столбцовc_2
(до двух , но не все триM_1 = M_2
,r_1 = r_2
,c_1 = c_2
). Строки и столбцы перестановки являются независимыми, так что если мы применим строки перестановкуr_1
кM_1
и строке перестановкуr_2
вM_2
столбцах как мультимножества должны быть равны. Поэтому для каждой группы я вычисляю все мультимножества столбцов, полученные путем применения перестановки строк к матрице в группе. Простой способ получить каноническое представление мультимножеств - это отсортировать столбцы, что также полезно на следующем шаге.Получив различные мультимножества столбцов, нам нужно выяснить, сколько
n!
перестановок каждого из них уникально. На этом этапе двойной подсчет может иметь место только в том случае, если в заданном мультимножестве столбцов есть повторяющиеся столбцы: нам нужно подсчитать количество вхождений каждого отдельного столбца в мультимножестве, а затем вычислить соответствующий коэффициент многочлена. Поскольку столбцы отсортированы, подсчет легко выполнить.Наконец мы добавляем их все.
Асимптотическая сложность не является тривиальной для вычисления с полной точностью, потому что мы должны сделать некоторые предположения о множествах. Мы оцениваем порядок
2^(2n-2) n!
столбцов мультимножеств, принимаяn^2 ln n
время для каждого (включая сортировку); если группировка занимает не больше, чемln n
фактор, у нас есть сложность времениTheta(4^n n! n^2 ln n)
. Но поскольку экспоненциальные факторы полностью доминируют над полиномиальными, это такTheta(4^n n!) = Theta((4n/e)^n)
.источник
Python2 / 3
Довольно наивный подход, на медленном языке:
Запустите, набрав
python script.py
.источник
from __future__ import print_function
(или что-то в этом роде)?return(1)
. Теперь заменитеreturn
наprint
:)Haskell
Нигде не так быстро, как у Питера - это довольно впечатляющая установка! Теперь с гораздо большим количеством кода, скопированного из Интернета. Использование:
источник