难度可以控制,且解法唯一,时间复杂度看运气。
首先,我们定义了一个 SudokuGenerator 类。然后,我们定义了 generate 方法来生成数独游戏。该方法生成了一个 9 × 9 的矩阵,初始值为 '.'。接着,使用 solveSudoku 方法来解决数独游戏,并将解决后的结果存放在生成的矩阵中。
在求解数独游戏时,我们使用深度优先搜索算法来实现。对于每个单元格,首先检查它是否有预设值(即是否为 '.'),如果有,直接跳过。如果没有,我们随机生成1~9的数字,并检查该数字是否符合数独规则,如果不符合规则,就换一个数字再次尝试,直到找到符合规则的数字。将符合规则的数字填入该单元格,并继续向后搜索,直到搜索完成整个数独游戏。
然后,我们定义了 removeNumbers 方法来删除数独游戏,使难度符合所选根据。在此方法中,我们使用深度优先搜索算法来逐步删除数独游戏中的数字。我们找到所有预设数字的单元格,并随机打乱它们的顺序。然后尝试删除单元格中的数字,并确保解法唯一,如果解法唯一,继续删除数字,否则回退上一个状态。
最后,我们定义了 isUnique 和 solve 方法来解决数独游戏。isUnique 方法用于确定给定的游戏是否具有唯一解。该方法使用深度优先搜索算法,在填写数字的过程中判断是否出现多个解决方案。 solve 方法解决数独游戏,将字符串表示为数独板,并返回解决结果的一个布尔值。
pythonimport random
class SudokuGenerator:
def __init__(self, difficulty):
# 限制在30和60之间
if difficulty < 30:
self.difficulty = 30
elif difficulty > 60:
self.difficulty = 60
else:
self.difficulty = difficulty
def generate(self):
board = [['.' for _ in range(9)] for _ in range(9)]
self.solveSudoku(board)
self.removeNumbers(board, self.difficulty)
return board
def solveSudoku(self, board):
def dfs(board, row, col):
if col == 9:
return dfs(board, row + 1, 0)
if row == 9:
return True
if board[row][col] != '.':
return dfs(board, row, col + 1)
nums = list(range(1, 10))
random.shuffle(nums)
for i in nums:
if not isValid(board, row, col, str(i)):
continue
board[row][col] = str(i)
if dfs(board, row, col + 1):
return True
board[row][col] = '.'
return False
def isValid(board, row, col, c):
for i in range(9):
if board[i][col] == c:
return False
if board[row][i] == c:
return False
if board[(row // 3) * 3 + i // 3][(col // 3) * 3 + i % 3] == c:
return False
return True
dfs(board, 0, 0)
def removeNumbers(self, board, difficulty):
def dfs(board, num):
if num == 0:
return True
lst = [(i, j) for i in range(9) for j in range(9) if board[i][j] != '.']
lst = sorted(lst, key=lambda x: random.random())
for i, j in lst:
c = board[i][j]
board[i][j] = '.'
if not self.isUnique(board):
board[i][j] = c
elif dfs(board, num - 1):
return True
else:
board[i][j] = c
return False
dfs(board, difficulty)
def isUnique(self, board):
s = ''.join([''.join(row) for row in board])
solver = SudokuSolver()
return solver.solve(s)
class SudokuSolver:
def solve(self, s):
board = [[s[i * 9 + j] for j in range(9)] for i in range(9)]
return self.solveSudoku(board)
def solveSudoku(self, board):
def dfs(board, row, col):
if col == 9:
return dfs(board, row + 1, 0)
if row == 9:
return True
if board[row][col] != '.':
return dfs(board, row, col + 1)
for i in range(1, 10):
if not isValid(board, row, col, str(i)):
continue
board[row][col] = str(i)
if dfs(board, row, col + 1):
return True
board[row][col] = '.'
return False
def isValid(board, row, col, c):
for i in range(9):
if board[i][col] == c:
return False
if board[row][i] == c:
return False
if board[(row // 3) * 3 + i // 3][(col // 3) * 3 + i % 3] == c:
return False
return True
return dfs(board, 0, 0)
generator = SudokuGenerator(50) # 挖空多少个格子
board = generator.generate()
for row in board:
print(row)
print(str(board).count("."))
检查时间复杂度:
pythonimport time
ties = []
for _ in range(100):
t0 = time.time()
generator = SudokuGenerator(60) # 挖空多少个格子
board = generator.generate()
# for row in board:
# print(row)
ties.append(time.time() - t0)
print(max(ties))
print(min(ties))
print(sum(ties) / len(ties))
得到的生成游戏所消耗的时间是:
254.41049194335938
0.02700185775756836
7.814508402347565
最大时间居然需要254秒,需要改进。
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!