Dancing Links - Diagrama extraído do artigo de Donald Knuth |
O primeiro passo é ver como considerar um Sudoku um problema de Cobertura Exata. Começamos examinando o conjunto de opções: cada uma das 9x9 posições do diagrama pode ter um dos dígitos de 1 a 9. Isto fornece as 9x9x9 = 729 linhas da nossa tabela.
Quais são as restrições e quais as colunas correspondentes? São as seguintes (atenção para não confundir linhas e colunas do diagrama do Sudoku com as linhas e colunas da tabela que será utilizada pelo algorítimo):
- Cada posição do diagrama pode conter um único dígito. É óbvio, mas essencial. Isto corresponde a 81 colunas (uma cada para posição do diagrama), indicando que é necessário escolher um dos nove dígitos para cada posição.
- Cada número só pode aparecer uma vez em cada linha do diagrama. São mais 81 colunas na tabela, cada coluna corresponde a uma combinação dígito x linha, indicando que que é necessário escolher uma das 9 colunas do diagrama onde aparecerá esta combinação.
- Cada número só pode aparecer uma vez em cada coluna do diagrama. São mais 81 colunas na tabela, cada coluna corresponde a uma combinação dígito x coluna, indicando que que é necessário escolher uma das 9 linhas do diagrama onde aparecerá esta combinação.
- Cada número só pode aparecer uma vez em cada bloco (sub-diagrama 3x3). São mais 81 colunas na tabela, cada coluna corresponde a uma combinação dígito x bloco, indicando que que é necessário escolher uma das 9 posições do bloco onde aparecerá esta combinação.
Agora é só seguir o algorítimo descrito no artigo do Knuth para construir o programa. A Wikipedia indica uma implementação do DLX, que você pode ver em https://github.com/blynn/dlx. Esta implementação é razoavelmente genérica, podendo ser usada tanto com Sudoku como com problemas de lógica que aparecem em revistas (exemplos aqui). Entretanto, esta implementação usa macros e alguns recursos da versões mais modernas de C que acabam escondendo um pouco o funcionamento,
A minha implementação (que você também pode ver no github) é específica para Sudoku mas (espero) um pouco mais legível.
Compensou a complexidade adicional? No meu micro de teste, o problema difícil, que demorava quase um minuto com a força bruta, foi resolvido instantaneamente.
Nenhum comentário:
Postar um comentário