Para um n fixo, considere n por n matrizes Toeplitz com entradas 0 ou 1. O objetivo é encontrar o determinante máximo sobre todas essas matrizes Toeplitz.
Tarefa
Para cada um n
de 1 em diante, imprima o determinante máximo sobre todas as n por n matrizes Toeplitz com entradas que são 0 ou 1. Deve haver uma saída por n
qual deve ter o determinante máximo e também uma matriz de exemplo que a atinja.
Ponto
Sua pontuação é a maior que n
seu código atinge em 2 minutos no meu computador. Para esclarecer um pouco, seu código pode ser executado por 2 minutos no total, isso não é de 2 minutos por n
.
Desempate
Se duas entradas obtiverem a mesma n
pontuação, a entrada vencedora será a que atingir a maior pontuação n
no menor tempo na minha máquina. Se as duas melhores entradas também forem iguais nesse critério, o vencedor será a resposta enviada primeiro.
Línguas e bibliotecas
Você pode usar qualquer idioma e bibliotecas disponíveis gratuitamente que desejar. Devo ser capaz de executar seu código, portanto, inclua uma explicação completa de como executar / compilar seu código no linux, se possível.
Minha máquina 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. Isso também significa que eu preciso poder executar seu código.
Pequenas respostas
Para n = 1..10, as saídas devem ser 1,1,2,3,5,9,32,56,125,315
Essa sequência não está no OEIS e, portanto, a entrada vencedora também propõe uma nova entrada lá.
Entradas até agora
n=10
n=11
por Vioz em Pythonn=9
por Tyilo em Cn=12
por Legendre em Jn=10
por Tensibai em Rn=14
por SteelRaven em C ++n=14
por RetoKoradi em C ++
n = 1..10
: ghostbin.com/paste/axkpaRespostas:
C ++ com pthreads
Isso chega a n = 14 em menos de 1 minuto na minha máquina. Mas como esse é apenas um laptop de dois núcleos, espero que a máquina de teste de oito núcleos possa terminar n = 15 em menos de 2 minutos. Demora cerca de 4:20 minutos na minha máquina.
Eu realmente esperava encontrar algo mais eficiente. Tem tem que haver uma maneira de calcular o determinate de uma matriz binária de forma mais eficiente. Eu queria criar algum tipo de abordagem de programação dinâmica que conte os termos +1 e -1 no cálculo determinante. Mas isso ainda não está bem definido até agora.
Como a recompensa está prestes a expirar, implementei a abordagem da força bruta padrão:
Eu testei isso no Mac OS, mas usei código semelhante no Ubuntu antes, então espero que isso compile e execute sem problemas:
.cpp
extensão, por exemplooptim.cpp
.gcc -Ofast optim.cpp -lpthread -lstdc++
.time ./a.out 14 8
. O primeiro argumento é o máximon
. 14 deve terminar em menos de 2 minutos, com certeza, mas seria ótimo se você pudesse tentar 15 também. O segundo argumento é o número de threads. Usar o mesmo valor que o número de núcleos da máquina normalmente é um bom começo, mas tentar algumas variações pode potencialmente melhorar os tempos.Entre em contato se tiver algum problema ao criar ou executar o código.
fonte
J
Atualização: código aprimorado para pesquisar mais da metade dos valores. Agora calcula
n=12
confortavelmente em 120 segundos (de 217 para 60).Você precisará da versão mais recente do J instalada.
Execute isso e mate quando dois minutos terminarem. Meus resultados (MBP 2014 - 16GB de RAM):
Tempo total de execução = 61,83s.
Apenas por diversão
Isso levou aproximadamente 210 segundos por conta própria.
fonte
n = 12
requer aproximadamente 18 GiB de memória.n=13
É possível alterar o.13
Na segunda-to-última linha para tê-lo calcular-se o que quiser.)Python 2
Esta é uma solução muito simples e provavelmente não vencerá o concurso. Mas ei, isso funciona!
Vou dar uma rápida visão geral do que exatamente está acontecendo.
n
. Por exemplo, quandon=2
, isso gerará um comprimento de matriz 2 n + 1 , em que cada linha terá o comprimento 2n-1. Ele ficaria assim:[[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
.n
tempo e corto os primeirosn
itens para gerar a matriz apropriada e usoscipy
para calcular o determinante, mantendo o controle do valor máximo. No final, simplesmente imprimo o máximo, incrementon
de 1 e continuo até 10 minutos.Para executar isso, você precisará do scipy instalado.
Editar 1: Alterou como as linhas iniciais foram criadas usando itertools.product, graças ao Sp3000!
Edição 2: Armazenamento removido de possíveis linhas iniciais para uma melhoria mínima na velocidade.
Editar 3: mudou para
scipy
ter mais controle sobre comodet
funcionou.Aqui estão alguns exemplos de saída na minha máquina doméstica (i7-4510U, 8 GB de RAM):
fonte
C ++
Bruteforce com o uso do OpenMP para paralelização e otimização simples para evitar a avaliação de determinantes para matrizes transpostas.
fonte
C
Ajuntar com:
Correr com:
Pode emitir o determinante máximo por
n = 1..10
~ 115 segundos no meu computador.O programa está apenas obtendo o determinante de todas as matrizes binárias possíveis de tamanho de Toeplitz
n
, porém todos os determinantes de matrizes de tamanho5x5
ou menores serão armazenados em cache usando a memorização.No começo, assumi erroneamente que todas as submatrizes de uma matriz de Toeplitz também serão uma matriz de Toeplitz; portanto, eu só precisava memorizar
2^(2n-1)
valores em vez de2^(n^2)
para cada uman
. Eu criei o programa antes de perceber meu erro, então esse envio é apenas uma correção desse programa.fonte
O(n!)
complexidade, então é melhor usar um algoritmo diferente.O(n^3)
, creio eu, que pode ser feito mais rápido com alguns algoritmos interessantes. Acredito que a maioria dos componentes internos usados aqui geralmente usa uma variante de decomposição para executar determinantes.O(n^2)
algoritmo se estiver atualizando minha resposta.O(n^2)
. Mas acho que o gargalo do problema está pesquisando entre osO(4^n)
muitos 0-1n
porn
matrizes.R
Você precisará instalar o R e os pacotes listados em
install.packages("package_name")
Não recebi menos de 2 minutos na minha máquina com esta versão (tenho que tentar com uma modificação paralela)
Chamada e saída:
Referência na minha máquina:
Para obter informações, para um intervalo de 1:11, são necessários 285 segundos.
fonte
PARI / GP, n = 11
Isso é força bruta, mas aproveitando
det(A^T) = det(A)
. Só estou postando para demonstrar como é fácil pular transposições. O bit mais baixob1
contém a célula superior esquerda e os outros bits mantêm o restante da linha superior.b2
mantém o restante da coluna esquerda. Nós simplesmente aplicamosb2 <= (b1>>1)
.Com relação à computação dos determinantes de Toeplitz no
O(n^2)
tempo: Na minha pesquisa limitada, continuei exigindo que todos os principais menores principais não fossem zero para que os algoritmos funcionassem, o que é um grande obstáculo para essa tarefa. Sinta-se livre para me dar sugestões, se você souber mais sobre isso do que eu.fonte
e_{k+1}
possui 4 vezes o número de componentes comoe_k
. Existem muitas omissões no artigo. Uma matriz invertível possui uma decomposição da LU se todos os principais menores principais não forem zero. (Observe os denominadores, por exemploa_0
- implicitamente, eles são garantidos como diferentes de zero). A singularidade vem de L ser unidade triangular. O autor também não mencionou estabilidade numérica. Caso o link fique indisponível, o artigo é "Sobre o cálculo dos determinantes das matrizes de Toeplitz", de Hsuan-Chu Li (2011).