You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Clingo的1{...}1规则实现数独的宫约束?

用Clingo的1{...}1基数约束实现数独宫约束

可以用1{...}1的基数约束规则实现数独的宫约束,你之前的代码未生效是因为整数除法使用错误、未定义对应谓词以及变量绑定逻辑问题,以下是修正后的实现方案:

问题分析

你之前尝试的宫约束代码存在三个核心问题:

  • Clingo中整数除法需用//,而非/(/是浮点除法,会导致宫编号计算为非整数,无法正确分组);
  • 未定义subgrid/1谓词,导致筛选条件subgrid(...)永远不成立;
  • 宫编号的计算逻辑和变量S的绑定顺序有误,无法正确关联宫的范围。

正确实现方案(两种写法)

写法1:先定义格子所属宫,再用基数约束

这种写法和你原有的行、列约束逻辑风格统一,先明确每个单元格对应的宫,再约束每个宫内数字唯一:

subgrid_size(3).
number(1..S*S) :- subgrid_size(S).
sudoku(X,Y,N) :- initial(X,Y,N).

% 基础约束:每个单元格有且仅有一个数字
1{sudoku(X,Y,N): number(N)}1 :- number(X), number(Y).
% 行约束:每行每个数字仅出现一次
1{sudoku(X,Y,N): number(X)}1 :- number(N), number(Y).
% 列约束:每列每个数字仅出现一次
1{sudoku(X,Y,N): number(Y)}1 :- number(X), number(N).

% 定义每个(X,Y)对应的宫G(使用整数除法//)
cell_in_grid(X,Y,G,S) :- 
    subgrid_size(S),
    number(X), number(Y),
    G = ((X-1)//S)*S + ((Y-1)//S) + 1.

% 宫约束:每个宫G内,每个数字N仅出现一次
1{sudoku(X,Y,N): cell_in_grid(X,Y,G,S)}1 :- 
    subgrid_size(S),
    number(N),
    number(G).

写法2:直接在基数约束中计算宫范围

无需额外定义cell_in_grid谓词,直接在基数约束的筛选条件里计算宫的X/Y边界:

subgrid_size(3).
number(1..S*S) :- subgrid_size(S).
sudoku(X,Y,N) :- initial(X,Y,N).

% 基础约束
1{sudoku(X,Y,N): number(N)}1 :- number(X), number(Y).
1{sudoku(X,Y,N): number(X)}1 :- number(N), number(Y).
1{sudoku(X,Y,N): number(Y)}1 :- number(X), number(N).

% 宫约束:直接计算宫G对应的X/Y范围,约束每个数字N在宫内唯一
1{sudoku(X,Y,N): 
    subgrid_size(S),
    X >= ((G-1)//S)*S + 1, X <= ((G-1)//S)*S + S,
    Y >= ((G-1)%S)*S + 1, Y <= ((G-1)%S)*S + S
}1 :- 
    subgrid_size(S),
    number(N),
    number(G).

两种方案的优势

和你找到的禁止约束方案相比,用1{...}1基数约束的写法:

  • 逻辑上和行、列约束完全统一,代码风格更一致;
  • 直接通过正向约束定义合法状态,而非禁止非法状态,更符合ASP的声明式编程思路。

内容的提问来源于stack exchange,提问作者xarxax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 17:42:37