Gurobi求解标准数独问题

问题导入

数独问题就是将9×9的网格填充上1~9的整数值,同时保证每个整数在每一行、每一列和每个3×3方格只出现一次。网格中分布有一些线索,你的任务就是填充剩余的网格数字。对于此问题,可以使用0-1变量优化求解。
在这里插入图片描述
标准数独问题只要有解就行,无需设置目标函数,即:可行解就是数独问题的解。

决策变量

在这里插入图片描述

约束条件

1.对于给定的初始元素,都认为是等式约束:
x i j k = 1 ∀ k = c i j ∈ C {{x}_{ijk}}=1\quad \forall k={{c}_{ij}}\in C xijk=1k=cijC
2.所有格子只能取一个值:
∑ k = 1 9 x i j k = 1 ∀ i , j = 1 , 2 , … 9 \sum\limits_{k=1}^{9}{{{x}_{ijk}}=1\quad \forall i,j=1,2,\ldots 9} k=19xijk=1i,j=1,2,9
3.每个数字在同一行、同一列、同一个九宫格只能出现一次:
∑ j = 1 9 x i j k = 1 ∀ i , k = 1 , 2 , … 9 \sum\limits_{j=1}^{9}{{{x}_{ijk}}=1\quad \forall i,k=1,2,\ldots 9} j=19xijk=1i,k=1,2,9
∑ i = 1 9 x i j k = 1 ∀ j , k = 1 , 2 , … 9 \sum\limits_{i=1}^{9}{{{x}_{ijk}}=1\quad \forall j,k=1,2,\ldots 9} i=19xijk=1j,k=1,2,9
∑ i = 1 + 3 × I 3 + 3 × I ∑ j = 1 + 3 × J 3 + 3 × J x i j k = 1 ∀ k = 1 , 2 , … 9 ; I , J = 0 , 1 , 2 \sum\limits_{i=1+3\times I}^{3+3\times I}{\sum\limits_{j=1+3\times J}^{3+3\times J}{{{x}_{ijk}}=1\quad \forall k=1,2,\ldots 9;I,J=0,1,2}} i=1+3×I3+3×Ij=1+3×J3+3×Jxijk=1k=1,2,9;I,J=0,1,2

算法程序

from gurobipy import *
import pandas as pd


def sudoku(matrix):
    #  创建模型
    model = Model('solve_sudoku')
    #  创建变量
    x = model.addVars(9, 9, 9, vtype=GRB.BINARY)
    #  更新变量环境
    model.update()
    #  创建目标函数
    model.setObjective(1, GRB.MINIMIZE)
    #  创建约束条件
    model.addConstrs(x[i, j, k] == 1 for i in range(9) for j in range(9) for k in range(9)
                     if isinstance(matrix.at[i, j], int) and k == matrix.at[i, j] - 1)
    model.addConstrs(sum(x.select(i, j, '*')) == 1 for i in range(9) for j in range(9))
    model.addConstrs(sum(x.select(i, '*', j)) == 1 for i in range(9) for j in range(9))
    model.addConstrs(sum(x.select('*', i, j)) == 1 for i in range(9) for j in range(9))
    model.addConstrs(sum(x[i + 3 * I, j + 3 * J, k] for i in range(3) for j in range(3)) == 1
                     for k in range(9) for I in range(3) for J in range(3))
    #  执行线性规划模型
    model.optimize()
    #  输出结果
    result = pd.DataFrame()
    for k, v in model.getAttr('x', x).items():
        if v == 1:
            result.at[k[0], k[1]] = k[2] + 1
    return result.astype(int)


if __name__=='__main__':
    matrix = pd.read_excel('F:\python\Gurobi_test\sudoku_test.xlsx', index_col=False, header=None, na_filter=False)
    print(sudoku(matrix))
    

运行结果

在这里插入图片描述
在这里插入图片描述

sudoku_test.xlsx内容

在这里插入图片描述
九宫格中的数字可以进行自定义,替换成你想要的数字。只要是标准数独问题,此程序均可以处理,而且使用Gurobi处理优化问题性能很高。

小结

如何安装和快速入门Gurobi?请参考gurobi 高效数学规划引擎

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值