Tengo un problema de combinatoria que me gustaría poner en el OEIS ; el problema es que no tengo suficientes términos. Este desafío de código es para ayudarme a calcular más términos, y el ganador será el usuario con el envío que contenga la mayor cantidad de términos.
El problema
Supongamos que le doy una matriz triangular de bombillas con longitud 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
Voy a encender tres bombillas que forman un triángulo equilátero "vertical" como en el siguiente ejemplo:
o
o x
o o o
o o o o
o x o o x
o o o o o o
Antes de encender las luces, su trabajo es eliminar la mayor cantidad posible de bombillas de la matriz, sin perder la capacidad de deducir el triángulo de bombillas que se ha encendido. Para ser claros, si se quitó una bombilla, no se enciende cuando se enciende su posición.
Por ejemplo, si eliminó las siguientes bombillas (marcadas con .
), solo vería las siguientes dos luces encendidas (marcadas con x
), lo que es suficiente para deducir de manera única la tercera posición (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
Sea a(n)
la cantidad máxima de bombillas que se pueden quitar sin introducir ambigüedades.
Ejemplo
Con un algoritmo ingenuo, he comprobado valores hasta un triángulo con longitud de lado 7, como se ve a continuación:
.
. . 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
Puntuación
La presentación que calcula la secuencia [a(2), a(3), ..., a(n)]
para las n más grandes gana. Si dos presentaciones tienen secuencias idénticas, entonces la que se publicó anteriormente gana.
Aunque no es necesario para el envío, sería instructivo para mí si publica una construcción de las matrices triangulares resultantes, como en el ejemplo anterior.
fuente
Respuestas:
Python 3 ,
n=8
Utiliza el solucionador CP-SAT de Google OR-Tools .
Después de ejecutarse durante ~ 30 segundos, genera lo siguiente:
n=9
a(9)=15
n=8
Cómo funciona
Por lo tanto, la pregunta puede reformularse como un problema SAT, con una restricción para cada par de triángulos.
PD: Me gustaría incluir un ejemplo para
n=8
, pero estoy teniendo problemas con el solucionador SAT que aparentemente quiere mantener las soluciones para sí mismo.fuente
Obteniendo las soluciones del programa @ Delfad0r
Extendí el programa de @ Delfad0r a soluciones de salida. También da resultados intermedios, por lo que obtienes resultados como este:
Este cálculo tomó varias horas.
Si se impacienta y presiona
Ctrl-C
después de encontrar una solución posiblemente no óptima, el programa mostrará esa solución. Por lo tanto, no lleva mucho tiempo obtener esto:Aquí está el programa extendido:
fuente
Python 3
Basado en gran medida en la respuesta de Delfad0r , en su mayoría sigue la misma progresión lógica al verificar los pares de triángulos y validar la configuración si no contiene pares de triángulos que fallen esta validación. Como no utilicé ninguna biblioteca además de itertools y copy, tengo control total sobre guardar los ejemplos encontrados en todo el programa.
El problema es que no es muy eficiente. Funciona muy rápido
n=5
, pero comienza a disminuir significativamente más allá de ese punto. Enn=6
, tarda alrededor de un minuto en correr, y es mucho más lenton=7
. Me imagino que se pueden hacer muchas correcciones de eficiencia con este programa, pero es un borrador rápido de una buena solución con mucha más flexibilidad para verificar el funcionamiento interno de este método. Trabajaré progresivamente en esto con el tiempo.fuente