python解数独的思路_python – 解决数独的算法

这是我在Python中的数独求解器.它使用简单的回溯算法来解决难题.

为简单起见,不进行输入验证或花哨输出.这是解决问题的最低限度代码.

算法

>查找给定单元格的所有合法值

>对于每个合法值,Go递归并尝试解决网格问题

它需要9X9网格部分填充数字.值为0的单元格表示未填充.

def findNextCellToFill(grid, i, j):

for x in range(i,9):

for y in range(j,9):

if grid[x][y] == 0:

return x,y

for x in range(0,9):

for y in range(0,9):

if grid[x][y] == 0:

return x,y

return -1,-1

def isValid(grid, i, j, e):

rowOk = all([e != grid[i][x] for x in range(9)])

if rowOk:

columnOk = all([e != grid[x][j] for x in range(9)])

if columnOk:

# finding the top left x,y co-ordinates of the section containing the i,j cell

secTopX, secTopY = 3 *(i//3), 3 *(j//3) #floored quotient should be used here.

for x in range(secTopX, secTopX+3):

for y in range(secTopY, secTopY+3):

if grid[x][y] == e:

return False

return True

return False

def solveSudoku(grid, i=0, j=0):

i,j = findNextCellToFill(grid, i, j)

if i == -1:

return True

for e in range(1,10):

if isValid(grid,i,j,e):

grid[i][j] = e

if solveSudoku(grid, i, j):

return True

# Undo the current cell for backtracking

grid[i][j] = 0

return False

测试代码

>>> input = [[5,1,7,6,0,0,0,3,4],[2,8,9,0,0,4,0,0,0],[3,4,6,2,0,5,0,9,0],[6,0,2,0,0,0,0,1,0],[0,3,8,0,0,6,0,4,7],[0,0,0,0,0,0,0,0,0],[0,9,0,0,0,0,0,7,8],[7,0,3,4,0,0,5,6,0],[0,0,0,0,0,0,0,0,0]]

>>> solveSudoku(input)

True

>>> input

[[5, 1, 7, 6, 9, 8, 2, 3, 4], [2, 8, 9, 1, 3, 4, 7, 5, 6], [3, 4, 6, 2, 7, 5, 8, 9, 1], [6, 7, 2, 8, 4, 9, 3, 1, 5], [1, 3, 8, 5, 2, 6, 9, 4, 7], [9, 5, 4, 7, 1, 3, 6, 8, 2], [4, 9, 5, 3, 6, 2, 1, 7, 8], [7, 2, 3, 4, 8, 1, 5, 6, 9], [8, 6, 1, 9, 5, 7, 4, 2, 3]]

以上是非常基本的回溯算法,在很多地方都有解释.但是我遇到的最有趣和自然的数独解决策略是从here开始的this one

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你答这个问题。 数独(Sudoku)是一种逻辑游戏,目的是在九宫格中填入数字,使得每一行、每一列和每一个九宫格内的数字都是唯一的。 以下是一个简单的数独游戏: ``` 0 0 0 | 2 6 0 | 7 0 1 6 8 0 | 0 7 0 | 0 9 0 1 9 0 | 0 0 4 | 5 0 0 ------+-------+------ 8 2 0 | 1 0 0 | 0 4 0 0 0 4 | 6 0 2 | 9 0 0 0 5 0 | 0 0 3 | 0 2 8 ------+-------+------ 0 0 9 | 3 0 0 | 0 7 4 0 4 0 | 0 5 0 | 0 3 6 7 0 3 | 0 1 8 | 0 0 0 ``` 其中,0 表示需要填充的数字。 以下是数独问题的 Python 实现: ```python def print_board(board): """ 打印数独棋盘 """ for i in range(len(board)): if i % 3 == 0 and i != 0: print("- - - - - - - - - - - - - ") for j in range(len(board[0])): if j % 3 == 0 and j != 0: print(" | ", end="") if j == 8: print(board[i][j]) else: print(str(board[i][j]) + " ", end="") def find_empty(board): """ 查找数独棋盘中的空格 """ for i in range(len(board)): for j in range(len(board[0])): if board[i][j] == 0: return (i, j) return None def is_valid(board, num, pos): """ 判断填入的数字是否合法 """ # 检查行 for i in range(len(board[0])): if board[pos[0]][i] == num and pos[1] != i: return False # 检查列 for i in range(len(board)): if board[i][pos[1]] == num and pos[0] != i: return False # 检查 3x3 方格 box_x = pos[1] // 3 box_y = pos[0] // 3 for i in range(box_y * 3, box_y * 3 + 3): for j in range(box_x * 3, box_x * 3 + 3): if board[i][j] == num and (i, j) != pos: return False return True def solve(board): """ 数独问题 """ empty = find_empty(board) if not empty: return True else: row, col = empty for i in range(1, 10): if is_valid(board, i, (row, col)): board[row][col] = i if solve(board): return True board[row][col] = 0 return False # 测试 board = [ [0, 0, 0, 2, 6, 0, 7, 0, 1], [6, 8, 0, 0, 7, 0, 0, 9, 0], [1, 9, 0, 0, 0, 4, 5, 0, 0], [8, 2, 0, 1, 0, 0, 0, 4, 0], [0, 0, 4, 6, 0, 2, 9, 0, 0], [0, 5, 0, 0, 0, 3, 0, 2, 8], [0, 0, 9, 3, 0, 0, 0, 7, 4], [0, 4, 0, 0, 5, 0, 0, 3, 6], [7, 0, 3, 0, 1, 8, 0, 0, 0] ] solve(board) print_board(board) ``` 代码中的 `print_board` 函数用于打印数独棋盘,`find_empty` 函数用于查找数独棋盘中的空格,`is_valid` 函数用于判断填入的数字是否合法,`solve` 函数用于数独问题。 在 `solve` 函数中,首先使用 `find_empty` 函数查找数独棋盘中的空格。如果没有空格,则表示数独问题已经得到解决,返回 True。否则,遍历数字 1-9,判断该数字是否可以填入当前位置。如果可以,则将该数字填入当前位置,然后递归调用 `solve` 函数。如果返回 True,表示数独问题已经得到解决,返回 True。否则,将当前位置恢复为 0,继续遍历下一个数字。如果遍历完所有的数字都不能得到解决,则返回 False。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值