La tarea es escribir código que pueda encontrar pequeñas fórmulas lógicas para sumas de bits.
El desafío general es que su código encuentre la fórmula lógica proposicional más pequeña posible para verificar si la suma de variables binarias 0/1 y es igual a algún valor x. Llamemos a las variables x1, x2, x3, x4, etc. Su expresión debe ser equivalente a la suma. Es decir, la fórmula lógica debería ser verdadera si y solo si la suma es igual a x.
Aquí hay una manera ingenua de hacerlo para empezar. Digamos y = 15 yx = 5. Elija las 3003 formas diferentes de elegir 5 variables y para cada una haga una nueva cláusula con el AND de esas variables AND y el AND de la negación de las variables restantes. Terminas con 3003 cláusulas de longitud exactamente 15 por un costo total de 45054.
Su respuesta debería ser una expresión lógica de ese tipo que se pueda pegar en Python, por ejemplo, para que pueda probarla. Si dos personas obtienen la misma expresión de tamaño, el código que ejecuta el más rápido gana.
Se le permite introducir nuevas variables en su solución. Entonces, en este caso, su fórmula lógica consiste en las variables binarias y, xy algunas variables nuevas. La fórmula completa sería satisfactoria si y solo si la suma de las variables y es igual a x.
Como ejercicio inicial, algunas personas pueden querer comenzar con y = 5 variables que se suman a x = 2. El método ingenuo le dará un costo de 50.
El código debe tomar dos valores y y x como entradas y generar la fórmula y su tamaño como salida. El costo de una solución es solo el recuento bruto de variables en su salida. Entonces (a or b) and (!a or c)
cuenta como 4. Los únicos operadores permitidos son and
, or
y not
.
Actualización Resulta que hay un método inteligente para resolver este problema cuando x = 1, al menos en teoría.
fuente
z[0] = y[0] and y[1]
, ¿cómo quieres que esto se indique?z[0]
represente,y[0] or y[1]
entonces solo necesitaría introducir una cláusula similar(y[0] or y[1]) or not z[0]
(o cualquier declaración equivalente que use los 3 operadores permitidos).Respuestas:
Python, 644
Un generador de ecuaciones recursivas simple.
S
genera una ecuación que se satisface si la lista devars
suma atotal
.Hay algunas mejoras obvias por hacer. Por ejemplo, hay muchas subexpresiones comunes que aparecen en la salida 15/5.
Genera:
fuente
not x[0] and not x[1] and not x[2]
aparece 5 veces en la expresión 15/5.Hubiera hecho esto un comentario, pero no tengo reputación. Quería comentar que los resultados de Kwon & Klieber (conocido como la codificación "Commander") para k = 1 han sido generalizados para k> = 2 por Frisch et al. "Codificaciones SAT de la restricción a lo sumo k". Lo que está preguntando es un caso especial de la restricción AM-k, con una cláusula adicional para garantizar At-Least-k, que es trivial, solo una disyunción de todas las variables a la restricción AM-k. Frisch es un investigador líder en modelado de restricciones, por lo que me sentiría cómodo sugiriendo que [(2k + 2 C k + 1) + (2k + 2 C k-1)] * n / 2 es el mejor límite conocido en cuanto al número de cláusulas requeridas, y k * n / 2 para el número de nuevas variables a introducir. Los detalles se encuentran en el documento citado, junto con las instrucciones de cómo se construyó esta codificación. Eso' Es bastante simple escribir un programa para generar esta fórmula, y creo que tal solución sería competitiva con cualquier otra solución que probablemente encuentre por ahora. HTH
fuente