如何在Gekko中实现'!='约束?数独求解器开发问题
在Gekko中实现数独的互不相同约束
问题背景
使用Gekko开发数独求解器(仅作兴趣研究),需要为每行、每列及3×3宫内的变量添加“互不相同”的约束。当前代码仅遵循预填充格子规则,其余格子均被填充为1.0。尝试直接用m.Equation(board[row,j] != board[row,i])表达不等约束时,出现“int类型对象无长度”错误;改用if3函数的方式也未达到预期效果。
正确实现方案
Gekko不支持直接用!=作为约束条件,对于整数变量,两个不同值的差的绝对值至少为1,因此可以借助m.abs()函数构建有效约束:
m.Equation(m.abs(board[row,i] - board[row,j]) >= 1)
修改后的完整代码
import itertools from gekko import GEKKO SQUARES = [ ((0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)), ((0,3),(0,4),(0,5),(1,3),(1,4),(1,5),(2,3),(2,4),(2,5)), ((0,6),(0,7),(0,8),(1,6),(1,7),(1,8),(2,6),(2,7),(2,8)), ((3,0),(3,1),(3,2),(4,0),(4,1),(4,2),(5,0),(5,1),(5,2)), ((3,3),(3,4),(3,5),(4,3),(4,4),(4,5),(5,3),(5,4),(5,5)), ((3,6),(3,7),(3,8),(4,6),(4,7),(4,8),(5,6),(5,7),(5,8)), ((6,0),(6,1),(6,2),(7,0),(7,1),(7,2),(8,0),(8,1),(8,2)), ((6,3),(6,4),(6,5),(7,3),(7,4),(7,5),(8,3),(8,4),(8,5)), ((6,6),(6,7),(6,8),(7,6),(7,7),(7,8),(8,6),(8,7),(8,8)) ] BOARD_DIMS = (9,9) PRE_FILLED_SQUARES = [ (0,1,2),(0,3,5),(0,5,1),(0,7,9),(1,0,8),(1,3,2), (1,5,3),(1,8,6),(2,1,3),(2,4,6),(2,7,7),(3,2,1), (3,6,6),(4,0,5),(4,1,4),(4,7,1),(4,8,9),(5,2,2), (5,6,7),(6,1,9),(6,4,3),(6,7,8),(7,0,2),(7,3,8), (7,5,4),(7,8,7),(8,1,1),(8,3,9),(8,5,7),(8,7,6) ] m = GEKKO() m.options.SOLVER = 1 # 使用APOPT求解器,适配整数规划场景 board = m.Array(m.Var, BOARD_DIMS, lb=1, ub=9, integer=True, value=1) # 预填充格子约束 for i,j,val in PRE_FILLED_SQUARES: board[i,j].value = val m.Equation(board[i,j] == val) # 行约束:每行元素互不相同 for row in range(BOARD_DIMS[0]): for i,j in itertools.combinations(range(BOARD_DIMS[1]), r=2): m.Equation(m.abs(board[row,i] - board[row,j]) >= 1) # 列约束:每列元素互不相同 for col in range(BOARD_DIMS[1]): for i,j in itertools.combinations(range(BOARD_DIMS[0]), r=2): m.Equation(m.abs(board[i,col] - board[j,col]) >= 1) # 3×3宫约束:每宫元素互不相同 for square in SQUARES: for (y,x),(y_prime,x_prime) in itertools.combinations(square, r=2): m.Equation(m.abs(board[y,x] - board[y_prime,x_prime]) >= 1) m.solve(disp=True) # 格式化打印结果 for row in board: print([int(v.value[0]) for v in row])
关键说明
- Gekko的APOPT求解器(
SOLVER=1)专门针对整数规划问题优化,适合数独这类带整数约束的场景。 - 直接使用
!=无法被Gekko的求解器解析,利用整数变量的特性,通过绝对值约束确保两个变量差值至少为1,等价于“互不相同”的逻辑。 - 移除了原代码中无效的
if3逻辑,避免因逻辑判断引入的约束失效问题。
内容的提问来源于stack exchange,提问作者phdavis1027
相关产品推荐
相关产品推荐

