AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79543108
Accepted
Guenther
Guenther
Asked: 2025-03-29 18:35:45 +0800 CST2025-03-29 18:35:45 +0800 CST 2025-03-29 18:35:45 +0800 CST

Pergunta de restrição de Minzinc - Sudoku similar

  • 772

Sou novo no Minizinc e quero resolver o seguinte problema.

Tenho uma matriz dada de 6x6 células. As linhas são numeradas de 1 a 6, as colunas de A a B. Todas as células devem ser preenchidas com dígitos de 1 a 9 por certas regras:

  1. Todos os 9 dígitos ocorrem exatamente 4 vezes na matriz.
  2. Vizinhos diretos em linha ou coluna não podem ter o mesmo valor.
  3. Todas as células em uma linha e todas as células em uma coluna terão valores diferentes.
  4. Existem algumas exceções de (3): a) A linha 2 tem dois "6". b) A linha 3 tem dois "3". c) A linha 4 tem dois "5". d) A linha 5 tem três "7". e) A linha 6 tem dois "8". f) A coluna B tem dois "3". g) A coluna D tem dois "8". h) A coluna F tem dois "9".
  5. A soma de todos os dígitos da linha 1 é >= 38.
  6. A soma de todos os dígitos da coluna E é = 21.
  7. A linha 2 não contém um "1".
  8. A linha 4 não contém um "4".
  9. A linha 5 não contém um "2".
  10. A linha 6 não contém um "3".
  11. A coluna C não contém um "2".
  12. A coluna B tem apenas dígitos pares, exceto os dois "3".
  13. A coluna A tem uma sequência crescente ou decrescente, por exemplo, "234567" ou "987654".

A maior dor de cabeça para mim ao construir o modelo em Minzinc são as restrições "contraditórias":

  • Todos os dígitos em uma única linha ou coluna devem ser diferentes.
  • Mas às vezes essa regra tem exceções.

Como isso pode ser realizado?

Obrigado antecipadamente e os melhores cumprimentos. Guenther

constraints
  • 4 4 respostas
  • 91 Views

4 respostas

  • Voted
  1. Best Answer
    Anonymous
    2025-03-30T19:30:38+08:002025-03-30T19:30:38+08:00

    Fiquei curioso sobre como modelar esse problema de forma concisa com Clingo ASP como uma alternativa ao minizinc. Não é Constraint Programming , mas é relacionado e bastante declarativo, então pode lhe dar algumas ideias:

    (na verdade, o minizinc também suporta o solucionador relacionado via flatzingo .)

    % Define rows and columns
    row(1..6).
    col(a;b;c;d;e;f).
    
    % Define digits
    digit(1..9).
    
    % Each cell has exactly one digit
    1 { value(R, C, D) : digit(D) } 1 :- row(R), col(C).
    
    % Each digit appears exactly 4 times in the grid
    :- digit(D), #count { R, C : value(R, C, D) } != 4.
    
    % No two adjacent cells in a row or column can have the same digit
    :- value(R1, C, D), value(R2, C, D), R1 = R2 - 1.
    :- value(R, C1, D), value(R, C2, D), adjacent_col(C1, C2).
    
    % Define adjacency in columns
    adjacent_col(a, b). adjacent_col(b, c). adjacent_col(c, d).
    adjacent_col(d, e). adjacent_col(e, f).
    adjacent_col(X, Y) :- adjacent_col(Y, X).
    
    % Row uniqueness with exceptions
    :- row(R), digit(D), #count { C : value(R, C, D) } > 1, not allowed_repeat(R, D).
    
    % Column uniqueness with exceptions
    :- col(C), digit(D), #count { R : value(R, C, D) } > 1, not allowed_repeat(C, D).
    
    % Define exceptions for uniqueness constraints
    allowed_repeat(2, 6).
    allowed_repeat(3, 3).
    allowed_repeat(4, 5).
    allowed_repeat(5, 7).
    allowed_repeat(6, 8).
    allowed_repeat(b, 3).
    allowed_repeat(d, 8).
    allowed_repeat(f, 9).
    
    % Enforce the exact count for the exceptions
    :- #count { C : value(2, C, 6) } != 2.
    :- #count { C : value(3, C, 3) } != 2.
    :- #count { C : value(4, C, 5) } != 2.
    :- #count { C : value(5, C, 7) } != 3.
    :- #count { C : value(6, C, 8) } != 2.
    :- #count { R : value(R, b, 3) } != 2.
    :- #count { R : value(R, d, 8) } != 2.
    :- #count { R : value(R, f, 9) } != 2.
    
    % Sum constraints row 1, col E
    :- #sum { D : value(1, C, D), col(C) } < 38.
    :- #sum { D : value(R, e, D), row(R) } != 21.
    
    % Forbidden digits in specific rows and columns
    :- value(2, C, 1).
    :- value(4, C, 4).
    :- value(5, C, 2).
    :- value(6, C, 3).
    :- value(R, c, 2).
    
    % Column B only has even digits except for two "3"
    :- value(R, b, D), D != 2, D != 4, D != 6, D != 8, D != 3.
    
    % Column A must be an ascending or descending sequence
    :- value(1, a, D1), value(2, a, D2), value(3, a, D3),
       value(4, a, D4), value(5, a, D5), value(6, a, D6),
       not ascending(D1, D2, D3, D4, D5, D6),
       not descending(D1, D2, D3, D4, D5, D6).
    
    ascending(D1, D2, D3, D4, D5, D6) :-
        value(1, a, D1), value(2, a, D2), value(3, a, D3),
        value(4, a, D4), value(5, a, D5), value(6, a, D6),
        D1 = D2-1, D2 = D3-1, D3 = D4-1, D4 = D5-1, D5 = D6-1.
    
    descending(D1, D2, D3, D4, D5, D6) :-
        value(1, a, D1), value(2, a, D2), value(3, a, D3),
        value(4, a, D4), value(5, a, D5), value(6, a, D6),
        D1 = D2+1, D2 = D3+1, D3 = D4+1, D4 = D5+1, D5 = D6+1.
    
    #show value/3.
    

    Saída: (copie e cole o código para executá-lo online )

    clingo version 5.7.2 (6bd7584d)
    Reading from stdin
    Solving...
    Answer: 1
    value(6,a,8) value(5,a,7) value(4,a,6) value(3,a,5) value(2,a,4) value(1,a,3) value(3,b,3) value(5,b,3) value(4,e,1) value(6,e,2) value(3,e,3) value(5,e,4) value(1,e,5) value(2,e,6) value(1,c,6) value(1,d,7) value(1,b,8) value(1,f,9) value(6,f,9) value(2,d,8) value(6,d,8) value(5,c,7) value(5,f,7) value(4,c,5) value(4,f,5) value(2,b,6) value(4,b,2) value(6,b,4) value(6,c,1) value(3,c,4) value(2,c,9) value(5,d,1) value(3,d,2) value(4,d,9) value(3,f,1) value(2,f,2)
    SATISFIABLE
    
    Models       : 1+
    Calls        : 1
    Time         : 3.559s (Solving: 0.59s 1st Model: 0.59s Unsat: 0.00s)
    CPU Time     : 0.000s
    

    A solução única como uma matriz:

    R\C UM B C E E F
    1 3 8 6 7 5 9
    2 4 6 9 8 6 2
    3 5 3 4 2 3 1
    4 6 2 5 9 1 5
    5 7 3 7 1 4 7
    6 8 4 1 8 2 9

    Atualizar:

    Adicionei a outra solução do OP ao modelo para verificar em ambas as direções:

    value(1,a,3). value(1,b,6). value(1,c,7). value(1,d,8). value(1,e,5). value(1,f,9).
    value(2,a,4). value(2,b,8). value(2,c,6). value(2,d,9). value(2,e,6). value(2,f,2).
    value(3,a,5). value(3,b,3). value(3,c,4). value(3,d,1). value(3,e,3). value(3,f,9).
    value(4,a,6). value(4,b,2). value(4,c,5). value(4,d,2). value(4,e,1). value(4,f,5).
    value(5,a,7). value(5,b,3). value(5,c,1). value(5,d,7). value(5,e,4). value(5,f,7).
    value(6,a,8). value(6,b,4). value(6,c,9). value(6,d,8). value(6,e,2). value(6,f,1).
    

    … e esta é a saída:

    clingo version 5.7.2 (6bd7584d)
    Reading from stdin
    Solving...
    UNSATISFIABLE
    
    Models       : 0
    Calls        : 1
    Time         : 2.543s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
    CPU Time     : 0.000s
    

    Dica:

    Dê uma olhada na linha 4!

    • 0
  2. Guenther
    2025-03-31T16:12:11+08:002025-03-31T16:12:11+08:00

    Obrigado por todas as dicas! Parece perfeito.

    A outra solução está aqui:

    UM B C E E F
    1 3 6 7 8 5 9
    2 4 8 6 9 6 2
    3 5 3 4 1 3 9
    4 6 2 5 2 1 5
    5 7 3 1 7 4 7
    6 8 4 9 8 2 1

    Obrigado novamente e os melhores cumprimentos,

    Guenther

    • 0
  3. Anonymous
    2025-03-31T19:34:49+08:002025-03-31T19:34:49+08:00

    Este é um trecho de código minizinc para forçar a linha 2 a ter dígitos diferentes, exceto 2x 6, com all_different_except() e count() :

    include "globals.mzn";  % Ensure all global constraints are available
    
    int: n = 6;  % 6x6 matrix
    set of int: D = 1..9;  % Digits 1-9
    array[1..n, 1..n] of var D: grid;  % 6x6 variable grid
    
    % Constraint: Row 2 must have different values except that 6 appears twice
    constraint all_different_except(grid[2, 1..n], {6});
    constraint count([grid[2, c] | c in 1..n], 6) = 2;
    
    %%% also works like this:
    %%% constraint count(grid[2, 1..n], 6, 2);
    
    solve satisfy;
    

    Saída:

    {'grid': [
      [1, 1, 1, 1, 1, 1],
      [6, 6, 3, 2, 1, 4],
      [1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1]
    ]}
    
    • 0
  4. Guenther
    2025-03-31T23:49:31+08:002025-03-31T23:49:31+08:00

    Ok, pessoal. Aqui está meu modelo MiniZinc, dando o resultado correto.

    % Solution for Puzzle
    %
    % Conditions:
    % row 1: sum>=38            column A: sequence asc. or desc.
    % row 2: two 6, no 1                column B: two 3 but no more odds
    % row 3: two 3              column C: no 2
    % row 4: two 5, no 4                column D: two 8
    % row 5: three 7, no 2          column E: sum = 21
    % row 6: two 8, no 3            column F: two 9
    
    include "globals.mzn";
    include "alldifferent.mzn";
    
    set of int: digits = 1..9;
    array[1..6,1..6] of var digits: matrix;
    
    % sum of row 1 >= 38
    constraint (matrix[1,1]+matrix[1,2]+matrix[1,3]+matrix[1,4]+matrix[1,5]+matrix[1,6]>=38);
    % sum of column E = 21
    constraint (matrix[1,5]+matrix[2,5]+matrix[3,5]+matrix[4,5]+matrix[5,5]+matrix[6,5]=21);
    
    % === Setting for Rows ===
    % All different in row 1
    constraint alldifferent( [ matrix[1,j] | j in 1..6 ]); 
    % All different except 2x6 in row 2
    constraint all_different_except(matrix[2, 1..6], {6});
    constraint count([matrix[2, j] | j in 1..6], 6) = 2;
    % No 1 in row 2
    constraint forall(j in 1..6) (matrix[2,j] != 1);
    % All different except 2x3 in row 3
    constraint all_different_except(matrix[3, 1..6], {3});
    constraint count([matrix[3, j] | j in 1..6], 3) = 2;
    % All different except 2x5 in row 4
    constraint all_different_except(matrix[4, 1..6], {5});
    constraint count([matrix[4, j] | j in 1..6], 5) = 2;
    % No 4 in row 4
    constraint forall(j in 1..6) (matrix[4,j] != 4);
    % All different except 3x7 in row 5
    constraint all_different_except(matrix[5, 1..6], {7});
    constraint count([matrix[5, j] | j in 1..6], 7) = 3;
    % No 2 in row 5
    constraint forall(j in 1..6) (matrix[5,j] != 2);
    % All different except 2x8 in row 6
    constraint all_different_except(matrix[6, 1..6], {8});
    constraint count([matrix[6, j] | j in 1..6], 8) = 2;
    % No 3 in row 6
    constraint forall(j in 1..6) (matrix[6,j] != 3);
    % Neighbors in rows cannot be the same
    constraint forall(i in 1..6) (forall(j in 2..6) (matrix[i,j] != matrix[i,j-1]));
    
    % === Setting for Columnns ===
    % All different in columns 1, 3, and 5
    constraint alldifferent( [ matrix[i,1] | i in 1..6 ]); 
    constraint alldifferent( [ matrix[i,3] | i in 1..6 ]); 
    constraint alldifferent( [ matrix[i,5] | i in 1..6 ]); 
    % All different except 2x3 in col B
    constraint all_different_except(matrix[1..6, 2], {3});
    constraint count([matrix[i, 2] | i in 1..6], 3) = 2;
    % Only even digits in column B except for the 2 Threes
    constraint forall(i in 1..6 where matrix[i,2]!=3) (matrix[i,2]=2 \/ matrix[i,2]=4 \/ matrix[i,2]=6 \/ matrix[i,2]=8);
    % No 2 in column C
    constraint forall(i in 1..6) (matrix[i,3] != 2);
    % All different except 2x8 in col D
    constraint all_different_except(matrix[1..6, 4], {8});
    constraint count([matrix[i, 4] | i in 1..6], 8) = 2;
    % All different except 2x9 in col F
    constraint all_different_except(matrix[1..6, 6], {9});
    constraint count([matrix[i, 6] | i in 1..6], 9) = 2;
    % Neighbors in cols cannot be the same
    constraint forall(i in 2..6) (forall(j in 1..6) (matrix[i,j] != matrix[i-1,j]));
    
    % Column A: asc. or desc. Sequence
    constraint (matrix[1,1]=matrix[2,1]+1/\matrix[2,1]=matrix[3,1]+1/\matrix[3,1]=matrix[4,1]+1/\
                matrix[4,1]=matrix[5,1]+1/\matrix[5,1]=matrix[6,1]+1) \/
               (matrix[1,1]+1=matrix[2,1]/\matrix[2,1]+1=matrix[3,1]/\matrix[3,1]+1=matrix[4,1]/\
                matrix[4,1]+1=matrix[5,1]/\matrix[5,1]+1=matrix[6,1]);
    
    % All Digits must occur 4x in the matrix
    constraint count([matrix[i,j] | i,j in 1..6], 1) = 4;
    constraint count([matrix[i,j] | i,j in 1..6], 2) = 4;
    constraint count([matrix[i,j] | i,j in 1..6], 3) = 4;
    constraint count([matrix[i,j] | i,j in 1..6], 4) = 4;
    constraint count([matrix[i,j] | i,j in 1..6], 5) = 4;
    constraint count([matrix[i,j] | i,j in 1..6], 6) = 4;
    constraint count([matrix[i,j] | i,j in 1..6], 7) = 4;
    constraint count([matrix[i,j] | i,j in 1..6], 8) = 4;
    constraint count([matrix[i,j] | i,j in 1..6], 9) = 4;
    
    solve satisfy;
    
    output ["S O L U T I O N \n",
            "=============== \n",
            "R/C\t A\t B\t C\t D\t E\t F \n",
            "-------------------------------------------------------\n",
            "1\t \(matrix[1,1])\t \(matrix[1,2])\t \(matrix[1,3])\t \(matrix[1,4])\t \(matrix[1,5])\t \(matrix[1,6])  \n",
            "2\t \(matrix[2,1])\t \(matrix[2,2])\t \(matrix[2,3])\t \(matrix[2,4])\t \(matrix[2,5])\t \(matrix[2,6])  \n",
            "3\t \(matrix[3,1])\t \(matrix[3,2])\t \(matrix[3,3])\t \(matrix[3,4])\t \(matrix[3,5])\t \(matrix[3,6])  \n",
            "4\t \(matrix[4,1])\t \(matrix[4,2])\t \(matrix[4,3])\t \(matrix[4,4])\t \(matrix[4,5])\t \(matrix[4,6])  \n",
            "5\t \(matrix[5,1])\t \(matrix[5,2])\t \(matrix[5,3])\t \(matrix[5,4])\t \(matrix[5,5])\t \(matrix[5,6])  \n",
            "6\t \(matrix[6,1])\t \(matrix[6,2])\t \(matrix[6,3])\t \(matrix[6,4])\t \(matrix[6,5])\t \(matrix[6,6])  \n" ];
    

    Tenho certeza de que várias partes do código poderiam ser codificadas de forma mais elegante. Mas estou feliz por ter construído minha primeira solução em MiniZinc até hoje.

    Obrigado por todas as suas contribuições!

    • 0

relate perguntas

  • O Timefold Solver aplica as restrições com base na prioridade/ordem das restrições (de ConstraintProvider) por padrão?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve