[英]Python Sudoko Solver - Backtracking
I have to devise a program to solve NxN sudoku using backtracking, N can be 1,4,9,16. 我必须设计一个使用回溯法解决NxN数独的程序,N可以是1,4,9,16。
I have managed to build a program that will solve 4x4 boards but for 9x9 boards and above I am stuck as to how to search for grids. 我设法建立了一个解决4x4电路板的程序,但对于9x9电路板及以上,我对于如何搜索网格仍然很困惑。
My code so far is below. 到目前为止,我的代码如下。
How would one approach searching the square(n) x square(n) grids? 一种方法如何搜索平方(n)x平方(n)网格?
def is_solved(board, n):
# If board is not solved, return False.
for x in range(n): # vertical coordinate
for y in range(n): # horizontal coordinate
if board[x][y] == 0: # zero representing an empty cell
return False
return True # else, the board is filled and solved, return True
def find_possibilities(board, i, j, n):
# Finds all possible numbers of an entry
possible_entries = {}
# initialize a dictionary with possible numbers to fill board
for num in range(1, n+1):
possible_entries[num] = 0
# horizontal
for y in range(0, n):
if not board[i][y] == 0: # current position is not 0, not empty
possible_entries[board[i][y]] = 1
# vertical
for x in range(0, n):
if not board[x][j] == 0:
possible_entries[board[x][j]] = 1
for num in range(1, n+1):
if possible_entries[num] == 0:
possible_entries[num] = num
else:
possible_entries[num] = 0
return possible_entries
def sudoku_solver(board):
n = len(board)
i = 0
j = 0
if is_solved(board, n):
print(board)
return True
else:
# find the first empty cell
for x in range(0, n):
for y in range(0, n):
if board[x][y] == 0:
i = x
j = y
break
# find all possibilities to fill board[i][j]
possibilities = find_possibilities(board, i, j, n)
for x in range(1, n + 1):
if not possibilities[x] == 0:
board[i][j] = possibilities[x]
return sudoku_solver(board)
# backtracking step
board[i][j] = 0 # resets the cell to an empty cell
def solve_sudoku(board):
if sudoku_solver(board):
return True
else:
return False
It seems to me that you would want to add a third check through that covers the grid that the current cell is in. For any of the board sizes, we might assume that the grid would be the square root of the board size. 在我看来,您希望添加第三条检查线以覆盖当前单元格所在的网格。对于任何板尺寸,我们都可以假定网格将是板尺寸的平方根。
Then each cell would be in a grid that has a minimum column number of int(i / math.sqrt(n))
and a maximum of int(column_minimum + i % math.sqrt(n))
and minimum row numbers of int(j / math.sqrt(n))
and maximum of int(row_minimum + j % math.sqrt(n))
. 然后,每个单元格将位于一个网格中,该网格的最小列数为
int(i / math.sqrt(n))
,最大列数为int(column_minimum + i % math.sqrt(n))
,最小列数为int(j / math.sqrt(n))
和最大int(row_minimum + j % math.sqrt(n))
。
Iterating through rows and columns and processing in the same way as your row and column checks should allow that final check to be made. 以与行和列检查相同的方式遍历行和列,并进行处理,应该可以进行最终检查。
This solution works: 此解决方案有效:
# surrounding grid
gridsize = int(math.sqrt(n))
minrow = i - int(i%gridsize)
maxrow = minrow + gridsize - 1
mincol = j - int(j%gridsize)
maxcol = mincol + gridsize - 1
for x in range(minrow, maxrow+1):
for y in range(mincol, maxcol+1):
if not board[x][y] == 1:
possible_entries[board[x][y]] = 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.