SAT é o problema de determinar se uma expressão booleana pode ser verdadeira. Por exemplo, (A) pode ser verdadeiro, configurando A = TRUE, mas (A &&! A) nunca pode ser verdadeiro. Esse problema é conhecido por ser NP-completo. Consulte Satisfação booleana .
Sua tarefa é escrever um programa para SAT que seja executado em tempo polinomial, mas pode não resolver todos os casos.
Para alguns exemplos, o motivo pelo qual não é realmente polinomial pode ser porque:
- Há um caso extremo que não é óbvio, mas tem um tempo de execução ruim
- O algoritmo realmente falha em resolver o problema em alguns casos inesperados
- Alguns recursos da linguagem de programação que você está usando têm, na verdade, um tempo de execução mais longo do que você esperaria razoavelmente
- Seu código realmente faz algo totalmente diferente do que parece estar fazendo
Você pode usar qualquer linguagem de programação (ou combinação de linguagens) que desejar. Você não precisa fornecer uma prova formal da complexidade do seu algoritmo, mas deve pelo menos fornecer uma explicação.
O principal critério para julgar deve ser o quão convincente é o código.
Este é um concurso de popularidade, por isso vence a resposta mais bem classificada em uma semana.
fonte
Respostas:
C #
"Aparece" é desnecessário. Eu posso escrever um programa que realmente seja executado em tempo polinomial para resolver problemas de SAT. Isso é bastante simples, de fato.
Impressionante. Por favor me envie o milhão de dólares. Sério, eu tenho um programa aqui que resolverá o SAT com tempo de execução polinomial.
Deixe-me começar afirmando que vou resolver uma variação do problema do SAT. Vou demonstrar como escrever um programa que exibe a solução exclusiva de qualquer problema 3-SAT . A avaliação de cada variável booleana deve ser exclusiva para o meu solucionador funcionar.
Começamos declarando alguns métodos e tipos auxiliares simples:
Agora vamos escolher um problema 3-SAT para resolver. Digamos
Vamos parênteses isso um pouco mais.
Codificamos isso assim:
E com certeza, quando executamos o programa, obtemos uma solução para o 3-SAT em tempo polinomial. De fato, o tempo de execução é linear no tamanho do problema !
fonte
Multi-idioma (1 byte)
O programa a seguir, válido em vários idiomas, principalmente funcionais e esotéricos, fornecerá a resposta correta para um grande número de problemas de SAT e possui complexidade constante (!!!):
Surpreendentemente, o próximo programa dará a resposta correta para todos os problemas restantes e tem a mesma complexidade. Então, você só precisa escolher o programa certo e terá a resposta correta em todos os casos!
fonte
Javascript
Usando o não determinismo iterado, o SAT pode ser resolvido em tempo polinomial!
Exemplo de uso:
A propósito, tenho orgulho de ter tido a oportunidade de utilizar dois dos recursos mais subutilizados do JavaScript, um ao lado do outro:
eval
ewith
.fonte
1000
loop for deve, de alguma forma, ser escalonado com o tamanho da entrada (algum escalonamento polinomial que não seja O (1)).Mathematica + Computação Quântica
Talvez você não saiba que o Mathematica vem com um computador quântico a bordo
A computação adiabática quântica codifica um problema a ser resolvido em um hamiltoniano (operador de energia) de forma que seu estado de energia mínima ("estado fundamental") represente a solução. Portanto, a evolução adiabática de um sistema quântico para o estado fundamental do Hamiltoniano e a medição subsequente dão a solução para o problema.
Definimos um subhamiltoniano que corresponde a
||
partes da expressão, com combinação apropriada de operadores de Pauli para variáveis e sua negaçãoOnde para expressões como esta
o argumento deve parecer
Aqui está o código para construir esse argumento a partir da expressão bool:
Agora construímos um hamiltoniano completo, resumindo os subhamiltonianos (o somatório corresponde a
&&
partes da expressão)E procure o menor estado de energia
Se obtivemos um valor próprio de zero, o vetor próprio é a solução
fonte
Três abordagens aqui, todas envolvem uma redução do SAT em sua língua franca geométrica 2D: quebra-cabeças lógicos não programáticos. As células no quebra-cabeça lógico correspondem a variáveis SAT, restrições a cláusulas.
Para uma explicação completa (e para revisar meu código quanto a erros!), Eu já publiquei algumas dicas sobre padrões dentro do espaço de solução que não é do programa. Consulte https://codereview.stackexchange.com/questions/43770/nonogram-puzzle-solution-space. Enumerar mais de 4 bilhões de soluções de quebra-cabeças e codificá-las para caber em uma tabela de verdade mostra padrões fractais - auto-similaridade e especialmente auto-afinidade. Essa redundância afim demonstra estrutura dentro do problema, explorável para reduzir os recursos computacionais necessários para gerar soluções. Também mostra a necessidade de feedback caótico em qualquer algoritmo bem-sucedido. Há um poder explicativo no comportamento da transição de fase, em que instâncias "fáceis" são aquelas que se encontram ao longo da estrutura grossa, enquanto instâncias "difíceis" exigem iteração adicional em detalhes, bastante ocultos às heurísticas normais. Se você deseja ampliar o canto desta imagem infinita (todas as instâncias de quebra-cabeça <= 4x4 codificadas), consulte http://re-curse.github.io/visualizing-intractability/nonograms_zoom/nonograms.html
Método 1. Extrapole a sombra do espaço da solução não-programa usando mapas caóticos e aprendizado de máquina (pense em funções de ajuste semelhantes às que geram o conjunto Mandelbrot).
Aqui está uma prova visual de indução. Se você pode escanear essas quatro imagens da esquerda para a direita e achar que tem uma boa idéia para gerar as 5as ... 6as ... etc. imagens ausentes, acabei de programá- lo como meu oracle NP para o problema de decisão da solução de nonogram existência. Por favor, avance para reivindicar seu prêmio como o supercomputador mais poderoso do mundo. De vez em quando, alimentarei você com eletricidade, enquanto o mundo agradece por suas contribuições computacionais.
Método 2. Use Transformadas de Fourier na versão de imagem booleana das entradas. As FFTs fornecem informações globais sobre frequência e posição em uma instância. Embora a porção de magnitude deva ser semelhante entre o par de entrada, suas informações de fase são completamente diferentes - contendo informações direcionadas sobre uma projeção de solução ao longo de um eixo específico. Se você for esperto o suficiente, poderá reconstruir a imagem da fase da solução através de uma superposição especial das imagens da fase de entrada. Transforme inversamente a fase e a magnitude comum de volta ao domínio do tempo da solução.
O que esse método poderia explicar? Existem muitas permutações das imagens booleanas com preenchimento flexível entre execuções contíguas. Isso permite um mapeamento entre a solução de entrada -> cuidando da multiplicidade, mantendo a propriedade das FFTs de mapeamentos bidirecionais e únicos entre o domínio do tempo <-> (frequência, fase). Isso também significa que não existe "nenhuma solução". O que diria é que, em um caso contínuo, existem soluções em escala de cinza que você não está considerando ao olhar para a imagem em dois níveis da resolução tradicional de quebra-cabeças sem programa.
Por que você não faria isso? É uma maneira horrível de calcular, pois as FFTs no mundo atual de ponto flutuante seriam altamente imprecisas em grandes instâncias. A precisão é um grande problema, e a reconstrução de imagens de magnitude quantificada e de fase geralmente cria soluções muito aproximadas, embora talvez não visualmente para os limiares do olho humano. Também é muito difícil criar esse negócio de superposição, pois o tipo de função que está realizando atualmente é desconhecido. Seria um esquema simples de média? Provavelmente não, e não há método de pesquisa específico para encontrá-lo, exceto a intuição.
Método 3. Encontre uma regra de autômato celular (de um possível ~ 4 bilhões de tabelas de regras para regras de dois estados de von Neumann) que resolva uma versão simétrica do quebra-cabeça do não-programa. Você usa uma incorporação direta do problema nas células, mostrada aqui.
Este é provavelmente o método mais elegante, em termos de simplicidade e bons efeitos para o futuro da computação. A existência desta regra não está comprovada, mas tenho um palpite de que ela existe. Aqui está o porquê:
Os nonogramas requerem muito feedback caótico no algoritmo para serem resolvidos exatamente. Isso é estabelecido pelo código de força bruta vinculado à Revisão de Código. A CA é a linguagem mais capaz de programar feedback caótico.
Ele parece bem, visualmente. A regra evoluiria através de uma incorporação, propagaria informações horizontal e verticalmente, interferiria e depois se estabilizaria em uma solução que conservasse o número de células definidas. Essa rota de propagação segue o caminho (para trás) em que você normalmente pensa ao projetar a sombra de um objeto físico na configuração original. Os nonogramas derivam de um caso especial de tomografia discreta; imagine-se sentado simultaneamente em dois tomógrafos com ponta de gatinho. É assim que os raios X se propagariam para gerar as imagens médicas. É claro que existem problemas de fronteira - as bordas do universo da CA não podem manter a propagação de informações além dos limites, a menos que você permita um universo toroidal. Isso também lança o quebra-cabeça como um problema periódico de valor-limite.
Explica várias soluções como estados transitórios em um efeito de oscilação contínua entre a troca de saídas como entradas e vice-versa. Explica instâncias que não têm solução como configurações originais que não conservam o número de células definidas. Dependendo do resultado real de encontrar essa regra, ela pode até aproximar instâncias insolúveis com uma solução próxima em que os estados das células são conservados.
fonte
C ++
Aqui está uma solução que é garantida para ser executada em tempo polinomial: ela é executada em
O(n^k)
quen
é o número de booleanos ek
é uma constante de sua escolha.fonte
bitfield
, talvez eu preferisse issostd::vector
.superfície 3d ruby / gnuplot
(ooh forte concorrência!) ... enfim ... uma imagem vale mais que mil palavras? estas são três parcelas de superfície separadas feitas no gnuplot do ponto de transição SAT. os eixos (x, y) são cláusula e contagem variável e a altura z é o número total de chamadas recursivas no solucionador. código escrito em ruby. amostras 10 x 10 pontos em 100 amostras cada. demonstra / usa princípios básicos de estatística e é uma simulação de Monte Carlo .
é basicamente um algoritmo de davis putnam executando em instâncias aleatórias geradas no formato DIMACS. esse é o tipo de exercício que idealmente seria feito nas aulas de ciências da computação em todo o mundo para que os alunos aprendessem o básico, mas quase não é ensinado especificamente ... talvez alguma razão para haver tantas provas falsas de P? = NP ? nem sequer há um bom artigo na Wikipedia descrevendo o fenômeno do ponto de transição (alguém que se interessa?), que é um tópico muito importante na física estatística e é fundamental também no CS. [a] [b] existem muitos artigos no CS sobre o ponto de transição no entanto, poucos parecem mostrar gráficos de superfície! (em vez disso, normalmente mostra fatias 2D).
o aumento exponencial em tempo de execução é claramente evidente em 1 r terreno. o selim que passa pelo meio de um r trama é o ponto de transição. os 2 nd e 3 rd gráficos mostram a transição satisfatível%.
[a] comportamento de transição de fase no CS ppt Toby Walsh
[b] probabilidade empírica de satisfação do k-SAT tcs.se
[c] grandes momentos em matemática empírica / experimental / (T) CS / SAT , TMachine blog
fonte