我的数独求解器哪里出了问题?
Posted
技术标签:
【中文标题】我的数独求解器哪里出了问题?【英文标题】:Where's the problem with my Sudoku solver? 【发布时间】:2022-01-19 21:35:12 【问题描述】:我在这个功能上工作的时间比预期的要长,因为我不想在这里问任何问题,或者看旁边的教程。 但是,我已经到了无法找到我的功能问题的地步。就是这样:
def sudoku_solver(sudoku, sol):
#Sudoku is solved (no 0s & correct order):
import numpy as np
check = np.all(sudoku)
if check:
sol += sudoku
return sol
#Number repeats in row:
filtered_rows = []
i = 0
while i < 9:
filtered_rows.append(list(filter(None, sudoku[i])))
i += 1
num_rows = len(filtered_rows)
for n in range(num_rows):
if len(filtered_rows[n]) > len(set(filtered_rows[n])):
return None
#Number repeats in column:
each_col = [list(i) for i in zip(*sudoku)]
filtered_cols = []
i = 0
while i < 9:
filtered_cols.append(list(filter(None, each_col[i])))
i += 1
num_cols = len(filtered_cols)
for s in range(num_cols):
if len(filtered_cols[s]) > len(set(filtered_cols[s])):
return None
#Number repeats in box:
i = 0
all_box = []
while i < 7:
y = 0
while y < 9:
new_number = sudoku[y][i:i + 3]
all_box += new_number
y += 1
if new_number == 0:
continue
i += 3
each_box = [all_box[i:i + 9] for i in range(0, len(all_box), 9)]
filtered_box = []
i = 0
while i < 9:
filtered_box.append(list(filter(None, each_box[i])))
i += 1
num_boxes = len(filtered_box)
for u in range(num_boxes):
if len(filtered_box[u]) > len(set(filtered_box[u])):
return None
#Recursive Cases
# Working in...
while i < 9:
y = 0
while y < 9:
if sudoku[i][y] == 0:
sudoku[i][y] += 1
sol_with_1 = sudoku_solver(sudoku, sol)
if sol_with_1 is not None:
return sol_with_1
sudoku[i][y] += 1
sol_with_2 = sudoku_solver(sudoku, sol)
if sol_with_2 is not None:
return sol_with_2
sudoku[i][y] += 1
sol_with_3 = sudoku_solver(sudoku, sol)
if sol_with_3 is not None:
return sol_with_3
sudoku[i][y] += 1
sol_with_4 = sudoku_solver(sudoku, sol)
if sol_with_4 is not None:
return sol_with_4
sudoku[i][y] += 1
sol_with_5 = sudoku_solver(sudoku, sol)
if sol_with_5 is not None:
return sol_with_5
sudoku[i][y] += 1
sol_with_6 = sudoku_solver(sudoku, sol)
if sol_with_6 is not None:
return sol_with_6
sudoku[i][y] += 1
sol_with_7 = sudoku_solver(sudoku, sol)
if sol_with_7 is not None:
return sol_with_7
sudoku[i][y] += 1
sol_with_8 = sudoku_solver(sudoku, sol)
if sol_with_8 is not None:
return sol_with_8
sudoku[i][y] -= 4
sol_with_9 = sudoku_solver(sudoku, sol)
if sol_with_9 is not None:
return sol_with_9
return None
y += 1
i += 1
#No solution
return "No Solution"
这不应该解决表示为这个的数独吗(0 是空格)?:
unsolved_sudoku = [[1, 6, 4, 0, 0, 0, 0, 0, 2],
[2, 0, 0, 4, 0, 3, 9, 1, 0],
[0, 0, 5, 0, 8, 0, 4, 0, 7],
[0, 9, 0, 0, 0, 6, 5, 0, 0],
[5, 0, 0, 1, 0, 2, 0, 0, 8],
[0, 0, 8, 9, 0, 0, 0, 3, 0],
[8, 0, 9, 0, 4, 0, 2, 0, 0],
[0, 7, 3, 5, 0, 9, 0, 0, 1],
[4, 0, 0, 0, 0, 0, 6, 7, 9]]`
当我输入一个已解决的数独时,它确实有效,所以我很确定问题出在递归代码中。我也考虑过使用“import as random”来做,每次迭代都会输出一个随机数,但我猜最后一个数字的概率太低了。
【问题讨论】:
您寻求帮助的问题是什么?有错误信息吗?它只是永远运行吗?使用信息更新您的帖子。 你无法通过暴力破解数独游戏。您有 45 个空槽。这意味着有 9**45 种可能性进行测试。那是 1 后跟 43 个零。你必须使用真正的逻辑启发式。 这是一个特别好的入门方法,因为它可以使用最简单的技术来解决。对于每个单元格,计算可以到达那里的数字列表(通过剔除同一行/列/象限中的值)。然后,如果一排只有一个空位,请将其填满。我认为这几乎就是这个谜题所需的全部内容。不要猜测;所有数独都可以解析求解,尽管许多数独需要比这更复杂的技术。 您在函数ssudoku_solver(sudoku, sol)
中作为 sol
传递的值是什么?你得到了什么输出?
【参考方案1】:
这是一个恰好解决这个数独的例子,虽然它不会解决任何困难的问题。
from pprint import pprint
unsolved_sudoku = [[1, 6, 4, 0, 0, 0, 0, 0, 2],
[2, 0, 0, 4, 0, 3, 9, 1, 0],
[0, 0, 5, 0, 8, 0, 4, 0, 7],
[0, 9, 0, 0, 0, 6, 5, 0, 0],
[5, 0, 0, 1, 0, 2, 0, 0, 8],
[0, 0, 8, 9, 0, 0, 0, 3, 0],
[8, 0, 9, 0, 4, 0, 2, 0, 0],
[0, 7, 3, 5, 0, 9, 0, 0, 1],
[4, 0, 0, 0, 0, 0, 6, 7, 9]]
all9 = set(range(1,10))
def find_possibles( grid,y, x ):
# Add the row.
allx = set( grid[y] )
# Add the column.
allx = allx.union( grid[dy][x] for dy in range(9))
# Add the quadrant.
x3 = (x // 3) * 3
y3 = (y // 3) * 3
allx = allx.union( [grid[y3+dy][x3+dx] for dy in range(3) for dx in range(3)] )
# Return what's left.
return all9-allx
def find_all_possibles( grid ):
filled = 0
for row in range(9):
for col in range(9):
if grid[row][col]:
continue
maybe = find_possibles( grid, row, col )
if len(maybe) == 1:
val = list(maybe)[0]
filled += 1
print( "Placing", val, "at", row, col )
grid[row][col] = val
return filled
while find_all_possibles(unsolved_sudoku):
pprint(unsolved_sudoku)
输出:
Placing 7 at 0 3
Placing 5 at 0 5
Placing 8 at 0 7
Placing 8 at 1 1
Placing 7 at 1 2
Placing 6 at 1 4
Placing 5 at 1 8
Placing 3 at 2 1
Placing 2 at 2 3
Placing 1 at 2 5
Placing 6 at 2 7
Placing 4 at 3 8
Placing 4 at 4 1
Placing 6 at 4 2
Placing 7 at 4 6
Placing 9 at 4 7
Placing 7 at 5 0
Placing 5 at 5 4
Placing 4 at 5 5
Placing 1 at 5 6
Placing 6 at 5 8
Placing 7 at 6 5
Placing 5 at 6 7
Placing 3 at 6 8
Placing 6 at 7 0
Placing 2 at 7 4
Placing 8 at 7 6
Placing 4 at 7 7
Placing 8 at 8 5
[[1, 6, 4, 7, 0, 5, 0, 8, 2],
[2, 8, 7, 4, 6, 3, 9, 1, 5],
[0, 3, 5, 2, 8, 1, 4, 6, 7],
[0, 9, 0, 0, 0, 6, 5, 0, 4],
[5, 4, 6, 1, 0, 2, 7, 9, 8],
[7, 0, 8, 9, 5, 4, 1, 3, 6],
[8, 0, 9, 0, 4, 7, 2, 5, 3],
[6, 7, 3, 5, 2, 9, 8, 4, 1],
[4, 0, 0, 0, 0, 8, 6, 7, 9]]
Placing 9 at 0 4
Placing 3 at 0 6
Placing 9 at 2 0
Placing 3 at 3 0
Placing 8 at 3 3
Placing 7 at 3 4
Placing 2 at 3 7
Placing 3 at 4 4
Placing 2 at 5 1
Placing 1 at 6 1
Placing 6 at 6 3
Placing 5 at 8 1
Placing 2 at 8 2
Placing 3 at 8 3
Placing 1 at 8 4
[[1, 6, 4, 7, 9, 5, 3, 8, 2],
[2, 8, 7, 4, 6, 3, 9, 1, 5],
[9, 3, 5, 2, 8, 1, 4, 6, 7],
[3, 9, 0, 8, 7, 6, 5, 2, 4],
[5, 4, 6, 1, 3, 2, 7, 9, 8],
[7, 2, 8, 9, 5, 4, 1, 3, 6],
[8, 1, 9, 6, 4, 7, 2, 5, 3],
[6, 7, 3, 5, 2, 9, 8, 4, 1],
[4, 5, 2, 3, 1, 8, 6, 7, 9]]
Placing 1 at 3 2
[[1, 6, 4, 7, 9, 5, 3, 8, 2],
[2, 8, 7, 4, 6, 3, 9, 1, 5],
[9, 3, 5, 2, 8, 1, 4, 6, 7],
[3, 9, 1, 8, 7, 6, 5, 2, 4],
[5, 4, 6, 1, 3, 2, 7, 9, 8],
[7, 2, 8, 9, 5, 4, 1, 3, 6],
[8, 1, 9, 6, 4, 7, 2, 5, 3],
[6, 7, 3, 5, 2, 9, 8, 4, 1],
[4, 5, 2, 3, 1, 8, 6, 7, 9]]
【讨论】:
以上是关于我的数独求解器哪里出了问题?的主要内容,如果未能解决你的问题,请参考以下文章