Eu tenho um problema combinatório que gostaria de colocar no OEIS - o problema é que não tenho termos suficientes. Esse desafio de código é ajudar-me a calcular mais termos, e o vencedor será o usuário com o envio contendo o maior número de termos.
O problema
Suponha que eu lhe forneça uma matriz triangular de lâmpadas com comprimento lateral :
o
o o
o o o
o o o o
o o o o o
o o o o o o
1 2 ... n
Vou acender três lâmpadas que formam um triângulo equilátero "vertical", como no exemplo a seguir:
o
o x
o o o
o o o o
o x o o x
o o o o o o
Antes de acender as luzes, seu trabalho é remover o maior número possível de lâmpadas da matriz - sem perder a capacidade de deduzir o triângulo de lâmpadas que foram acesas. Para ficar claro, se uma lâmpada foi removida, ela não acende quando sua posição é ligada.
Por exemplo, se você removesse as seguintes lâmpadas (marcadas por .
), você apenas veria as duas luzes seguintes acesas (marcadas por x
), o que é suficiente para deduzir exclusivamente a terceira posição (apagada):
. .
. o . x
. . o . . o
o o o . => o o o .
o o o o . o x o o . <- the third unlit position
o . . . o o o . . . o o
Seja a(n)
o número máximo de lâmpadas que podem ser removidas sem introduzir ambiguidades.
Exemplo
Com um algoritmo ingênuo, verifiquei valores até um triângulo com o comprimento lateral 7, como mostrado abaixo:
.
. . o
. . o o . o
. . . . . o . o o .
. . . . o o o o o . o o . o .
. . . . o o o o . o o o o o . o . o . o o
. . . o o . o o o o . . o o o . . . o o o . o . o o o
a(2) = 3 a(3) = 4 a(4) = 5 a(5) = 7 a(6) = 9 a(7) = 11
Pontuação
A submissão que calcula a sequência [a(2), a(3), ..., a(n)]
para os maiores n ganhos. Se dois envios tiverem seqüências idênticas, o que foi postado anteriormente vence.
Embora não seja necessário para a apresentação, seria instrutivo para mim se você postar uma construção das matrizes triangluar resultantes, como no exemplo acima.
fonte
Respostas:
Python 3 ,
n=8
Usa o solucionador de CP-SAT do Google OR-Tools .
Depois de executar por ~ 30 segundos, ele gera o seguinte:
Eu não tentei esperarn6 . Após menos de 30 minutos de computação, descobri isson=9
, pois provavelmente levaria horas (o número de restrições cresce como )a(9)=15
. Estou deixando minha pontuação comon=8
porque, no momento, as restrições de tempo não são claras, mas meia hora provavelmente é muito longa.Como funciona
Tome dois triângulos equilaterais distintos e . Para evitar ambiguidade, deve haver pelo menos uma lâmpada em um vértice pertencendo exatamente a um de e .T 2 T 1 T 2T1 T2 T1 T2
Assim, a questão pode ser reformulada como um problema de SAT, com uma restrição para cada par de triângulos.
PS: Gostaria muito de incluir um exemplo
n=8
, mas estou tendo problemas com o solucionador SAT, que aparentemente deseja manter as soluções por si só.fonte
Obtendo as soluções do programa @ Delfad0r
Estendi o programa da @ Delfad0r para soluções de saída. Também fornece resultados intermediários, para que você obtenha uma saída como esta:
Este cálculo levou várias horas.
Se você ficar impaciente e pressionar
Ctrl-C
após encontrar alguma solução possivelmente não ótima, o programa mostrará essa solução. Portanto, não demora muito para conseguir isso:Aqui está o programa estendido:
fonte
Python 3
Baseado fortemente na resposta de Delfad0r , segue principalmente a mesma progressão lógica verificando pares de triângulos e validando a configuração se ela não contiver pares de triângulos que falhem nessa validação. Como não usei nenhuma biblioteca além de ferramentas e cópias, tenho controle total sobre os exemplos encontrados ao longo do programa.
O problema é que não é muito eficiente. Ele roda muito rápido
n=5
, mas começa a desacelerar significativamente além desse ponto. Àsn=6
, leva cerca de um minuto para ser executado, e é muito mais lenton=7
. Imagino que existem muitas correções de eficiência que podem ser feitas com este programa, mas é um rascunho rápido de uma boa solução com muito mais flexibilidade para verificar o funcionamento interno desse método. Vou trabalhar gradualmente nisso com o tempo.fonte