A tarefa é escrever código que possa encontrar pequenas fórmulas lógicas para somas de bits.
O desafio geral é que seu código encontre a menor fórmula lógica proposicional possível para verificar se a soma das variáveis binárias 0/1 de y é igual a algum valor x. Vamos chamar as variáveis x1, x2, x3, x4 etc. Sua expressão deve ser equivalente à soma. Ou seja, a fórmula lógica deve ser verdadeira se e somente se a soma for igual a x.
Aqui está uma maneira ingênua de fazer isso para começar. Diga y = 15 ex = 5. Escolha todas as 3003 maneiras diferentes de escolher 5 variáveis e, para cada uma, faça uma nova cláusula com o AND dessas variáveis AND o AND da negação das variáveis restantes. Você termina 3003 cláusulas cada uma com exatamente 15 para um custo total de 45054.
Sua resposta deve ser uma expressão lógica desse tipo que pode ser colada no python, digamos, para que eu possa testá-lo. Se duas pessoas obtiverem a mesma expressão de tamanho, o código que executa mais rápido vence.
Você tem permissão para introduzir novas variáveis em sua solução. Portanto, neste caso, sua fórmula lógica consiste nas variáveis binárias y, x e em algumas novas variáveis. A fórmula inteira seria satisfatória se e somente se a soma das variáveis y for igual a x.
Como exercício inicial, algumas pessoas podem querer começar com y = 5 variáveis adicionando x = 2. O método ingênuo dará um custo de 50.
O código deve usar dois valores yex como entradas e gerar a fórmula e seu tamanho como saída. O custo de uma solução é apenas a contagem bruta de variáveis em sua saída. Então (a or b) and (!a or c)
conta como 4. Os únicos operadores permitidos são and
, or
e not
.
Atualização Acontece que existe um método inteligente para resolver esse problema quando x = 1, pelo menos em teoria.
fonte
z[0] = y[0] and y[1]
, como você quer isso indicado?z[0]
representey[0] or y[1]
, seria necessário introduzir uma cláusula que se parece com(y[0] or y[1]) or not z[0]
(ou qualquer declaração equivalente usando os 3 operadores permitidos).Respostas:
Python, 644
Um simples gerador de equações recursivas.
S
gera uma equação que é satisfeita se a lista devars
somartotal
.Existem algumas melhorias óbvias a serem feitas. Por exemplo, existem muitas subexpressões comuns que aparecem na saída 15/5.
Gera:
fonte
not x[0] and not x[1] and not x[2]
aparece 5 vezes na expressão 15/5.Eu teria feito disso um comentário, mas não tenho reputação. Eu gostaria de comentar que os resultados de Kwon & Klieber (conhecidos como codificação "Commander") para k = 1 foram generalizados para k> = 2 por Frisch et al. "Codificações SAT da restrição At-Most-k." O que você está perguntando é um caso especial da restrição AM-k, com uma cláusula adicional para garantir At-Least-k, que é trivial, apenas uma disjunção de todas as variáveis para a restrição AM-k. Frisch é um pesquisador líder em modelagem de restrições, então eu me sentiria à vontade sugerindo que [(2k + 2 C k + 1) + (2k + 2 C k-1)] * n / 2 é o melhor limite conhecido no número de cláusulas necessárias e k * n / 2 para o número de novas variáveis a serem introduzidas. Os detalhes estão no artigo citado, juntamente com as instruções de como essa codificação deve ser construída. Isto' É bastante simples escrever um programa para gerar essa fórmula e acho que essa solução seria competitiva com outras soluções que você provavelmente encontrará por enquanto. HTH.
fonte