关于数独的介绍
数独的规则
数独生成的规则为:根据9X9表盘上面的已知数字,推理出所有剩余空格的数字,并且需满足每一行、每一列、每个九宫格内的数字均含1-9,不重复。
本次实验的介绍
实验目的
输出不同难度的数独题目和答案
设计思路
①采用随机填数的方法生成数独初始盘
②采用深度优先求解数独
③采用挖洞法对求解出的数独进行挖洞
④再次采用深度优先对数独进行求解
算法设计
导入所需库
import numpy as np
import random
导入Numpy库,使用矩阵来保存和处理数独数据。使用zeros方法生成9X9的的0矩阵,初始化数独。导入Random库的randint方法来生成随机的行标和列标用来随机定位一个单元格。
初始化九宫格
class Sudoku:
def __init__(self):
# 初始化九宫格
self.grids= np.zeros((9, 9), dtype=int, order='C')
self.possibleNums= {
1, 2, 3, 4, 5, 6, 7, 8, 9}
# 用于挖洞时保存挖好的数独
self.uniqueGrids = None
定义约束条件
# 由三个约束条件剔除数据
def get_possible(self, row, col):
bRow, bCol = row // 3, col // 3
# 提取行标为row的行
rowSet = set(self.grids[row])
# 提取列标为col的列
colSet = set(self.grids[:,col])
# 由行标列表取出所在的3*3小九宫格
blockSet = set(self.grids[bRow * 3: bRow * 3 + 3,
bCol * 3: bCol * 3 + 3].reshape(9))
# 从possible中剔除所在行、所在列和所在小九宫格里的相同的数字
return self.possibleNums - rowSet - colSet - blockSet
深度优先方法解数独
def dfs(self):
for row in range(9):
for col in range(9):
# 从0行0列开始寻找空白格
if self.grids[row, col] == 0:
# 用get_possible得到当前空白格可以填入的数值
possible = self.get_possible(row, col)
# 深度优先,填入第一个值,递归填入剩下空白格的值
# 如果无法正确填写,就还回归上一个刚填的格,置0后重新填入possible里第二值
# 直到所有空白格都正确填入
for value in possible:
self.grids[row, col] = value
if self.dfs():
return True
self.grids[row, col] = 0
return False
return True
拉斯维加斯算法生成数独
def lasVegas(self, initGivenCount):
# initGivenCount为初始给定数字的个数
while initGivenCount:
# 用随机行列定位一个单元格
row = random.randint(0, 8)
col = random.randint(0, 8)
# 选中空白格,且避免再次选中已经填入的单元格
if self.grids[row, col] == 0:
# 随机在可能的取值中取一个数,避免初始的宫格中都是1,2,3