fundo
Uma matriz binária de Hankel é uma matriz com diagonais de inclinação constantes (diagonais inclinadas positivas) contendo apenas 0
s e 1
s. Por exemplo, uma matriz Hankel binária 5x5 se parece com
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
Onde a, b, c, d, e, f, g, h, i
estão 0
ou 1
.
Vamos definir uma matriz M como Hankelable se houver uma permutação da ordem das linhas e colunas de M para que M seja uma matriz de Hankel. Isso significa que é possível aplicar uma permutação na ordem das linhas e uma possivelmente diferente nas colunas.
O desafio
O desafio é contar quantos Hankelable n
por n
matrizes existem para todosn
até como um valor maior possível.
Resultado
Para cada número inteiro n de 1 para cima, imprima o número de Hankelablen
por n
matrizes com entradas que são 0
ou1
.
Para n = 1,2,3,4,5
as respostas devem ser2,12,230,12076,1446672
. (Obrigado ao orlp pelo código para produzi-los.)
Prazo
Vou executar o seu código na minha máquina e pará-lo após 1 minuto. O código que gera as respostas corretas até o maior valor de n ganha. O limite de tempo é para tudo, desde n = 1
o maior valor den
para o qual você responde.
O vencedor será a melhor resposta até o final do sábado, 18 de abril.
Desempate
No caso de um empate por um tempo máximo n
, cronometrarei quanto tempo leva para dar as saídas n+1
e a mais rápida vencer. No caso em que eles sejam executados ao mesmo tempo em até um segundo n+1
, a primeira submissão vence.
Línguas e bibliotecas
Você pode usar qualquer idioma que tenha um compilador / intérprete disponível gratuitamente / etc. para Linux e quaisquer bibliotecas que também estão disponíveis gratuitamente para Linux.
Minha maquina
Os horários serão executados na minha máquina. Esta é uma instalação padrão do ubuntu em um processador AMD FX-8350 de oito núcleos em uma placa-mãe Asus M5A78L-M / USB3 (soquete AM3 +, 8GB DDR3). Isso também significa que eu preciso poder executar seu código. Como conseqüência, use apenas software livre facilmente disponível e inclua instruções completas sobre como compilar e executar seu código.
Notas
Eu recomendo não repetir todas as matrizes n por n e tentar detectar se cada uma tem a propriedade que eu descrevo. Primeiro, há muitos e, segundo, parece não haver uma maneira rápida de fazer essa detecção .
Entradas principais até agora
- n = 8 por Peter Taylor. Java
- n = 5 por orlp. Pitão
fonte
n=6
o total é260357434
. Eu acho que a pressão da memória é um problema maior que o tempo da CPU.Respostas:
Java (n = 8)
Salvar como
HankelCombinatorics.java
, compilar comojavac HankelCombinatorics.java
, executar comojava -Xmx2G HankelCombinatorics
.Com
NUM_THREADS = 4
a minha máquina quad-core fica20420819767436
porn=8
em 50 a 55 segundos decorridos, com uma boa quantidade de variabilidade entre as execuções; Espero que ele gerencie facilmente o mesmo em sua máquina octa-core, mas levará uma hora ou mais para obtê-lon=9
.Como funciona
Dado
n
, existem matrizes2^(2n-1)
bináriasn
xn
Hankel. As linhas podem ser permutadas den!
maneiras e as colunas den!
maneiras. Tudo o que precisamos fazer é evitar a contagem dupla ...Se você calcular a soma de cada linha, nem permutar as linhas nem permutar as colunas alterará o conjunto múltiplo de somas. Por exemplo
possui soma de linha multiset
{3, 3, 2, 2, 2}
e, assim como todas as matrizes Hankelable derivadas dela. Isso significa que podemos agrupar as matrizes de Hankel por esses multisets de soma de linhas e manipular cada grupo independentemente, explorando vários núcleos de processador.Há também uma simetria explorável: as matrizes com mais zeros do que aquelas estão em bijeção com as matrizes com mais zeros.
Dupla contagem ocorre quando matriz de Hankel
M_1
com permutação de linhar_1
e coluna de permutaçãoc_1
corresponde matriz de HankelM_2
com permutação de linhar_2
e coluna de permutaçãoc_2
(com um máximo de dois, mas não todos os trêsM_1 = M_2
,r_1 = r_2
,c_1 = c_2
). As linhas e colunas permutações são independentes, por isso, se nós aplicamos fila permutaçãor_1
paraM_1
e linha de permutaçãor_2
paraM_2
, as colunas como multisets devem ser iguais. Portanto, para cada grupo, calculo todos os conjuntos múltiplos de colunas obtidos aplicando uma permutação de linha a uma matriz no grupo. A maneira mais fácil de obter uma representação canônica dos multisets é classificar as colunas, o que também é útil na próxima etapa.Tendo obtido os diversos conjuntos de colunas distintos, precisamos descobrir quantas
n!
permutações de cada um são únicas. Nesse ponto, a contagem dupla só pode ocorrer se um determinado conjunto múltiplo de colunas tiver colunas duplicadas: o que precisamos fazer é contar o número de ocorrências de cada coluna distinta no conjunto múltiplo e calcular o coeficiente multinomial correspondente. Como as colunas são classificadas, é fácil fazer a contagem.Finalmente, adicionamos todos eles.
A complexidade assintótica não é trivial para calcular com precisão total, porque precisamos fazer algumas suposições sobre os conjuntos. Avaliamos a ordem dos
2^(2n-2) n!
vários conjuntos de colunas, levandon^2 ln n
tempo para cada um (incluindo a classificação); se o agrupamento não leva mais que umln n
fator, temos complexidade de tempoTheta(4^n n! n^2 ln n)
. Mas desde que os fatores exponenciais dominam completamente os polinomiais, é issoTheta(4^n n!) = Theta((4n/e)^n)
.fonte
Python2 / 3
Abordagem bastante ingênua, em uma linguagem lenta:
Execute digitando
python script.py
.fonte
from __future__ import print_function
(ou algo assim)?return(1)
. Agora substituareturn
porprint
:)Haskell
Nem tão rápido quanto o de Peter - é uma configuração bastante impressionante que ele conseguiu! Agora, com muito mais código copiado da internet. Uso:
fonte