基于Backtracking method的Python数独生成器代码报错:填充至(0,7)后终止
数独生成器回溯逻辑错误排查
问题描述
- 基于回溯法编写Python数独生成器,行、列、3×3网格检查函数已单独验证正常
- 代码从起始位置随机填充数字,不满足检查条件时循环尝试,直到符合要求
- 运行后仅填充至
(row,col)=(0,7)位置就终止,确定错误出在第73-77行
原代码
from random import choice a = [['-','-','-', '-','-','-', '-','-','-'],\ ['-','-','-', '-','-','-', '-','-','-'],\ ['-','-','-', '-','-','-', '-','-','-'],\ ['-','-','-', '-','-','-', '-','-','-'],\ ['-','-','-', '-','-','-', '-','-','-'],\ ['-','-','-', '-','-','-', '-','-','-'],\ ['-','-','-', '-','-','-', '-','-','-'],\ ['-','-','-', '-','-','-', '-','-','-'],\ ['-','-','-', '-','-','-', '-','-','-']] def sudoku_board(): # 返回格式化后的数独棋盘 board = '' for i in range(9): if i==3 or i==6: board+='\n\n' else: board += '\n' for j in range(9): if j==2 or j==5: board += str(a[i][j]) + '\t' else: board+= str(a[i][j]) + ' ' return board def col_check(x,y,num): # 检查列中是否存在重复数字,重复返回1,否则返回0 col = 0 for m in range(9): if a[m][y] == str(num): col = 1 break return col def row_check(x,y,num): # 检查行中是否存在重复数字,重复返回1,否则返回0 row = 0 for m in range(9): if m!=y and a[x][m] == str(num): row = 1 break return row def grid_check(x,y,num): # 检查3×3网格中是否存在重复数字,重复返回1,否则返回0 grid = 0 for m in [(x//3),(x//3)+1,(x//3)+2]: for n in [(y//3),(y//3)+1,(y//3)+2]: if a[m][n] == str(num): grid = 1 break return grid i,j = 0,0 while i!=8 and j!=8: num = [1,2,3,4,5,6,7,8,9] rand_num = choice(num) c=0 while col_check(i,j,rand_num)==1 or row_check(i,j,rand_num)==1 or grid_check(i,j,rand_num)==1: if c<9: c+=1 num.remove(rand_num) rand_num = choice(num) else: c=0 num = [1,2,3,4,5,6,7,8,9] if j==True: j-=1 else: i-=1 a[i][j]=str(rand_num) if j==8: j=0 if i!=8: i+=1 else: break else: j+=1 print(sudoku_board())
错误分析与修复
核心错误点(第73-77行)
- 索引判断逻辑错误:
j==True是完全错误的判断——j是0-8的整数,只有j=1时会被视为True,其他非零列索引(如2-8)都会被判定为False,导致错误地回退行索引i,而非列索引j。 - 未清空回溯位置的数值:回溯时没有将当前位置重置为
'-',之前填充的数字会留在棋盘上,干扰后续的检查逻辑。 - 回溯逻辑不完整:当回退到行首(j=0)时,未正确切换到上一行的最后一列(i-1,8),导致索引混乱。
修正后的回溯代码段
else: c=0 num = [1,2,3,4,5,6,7,8,9] # 清空当前位置,避免残留数值影响后续检查 a[i][j] = '-' # 正确的回溯逻辑:先回退列,列到0则回退行并将列设为8 if j > 0: j -= 1 else: j = 8 i -= 1
额外修正:外层循环条件
原循环条件while i!=8 and j!=8会导致当i=8且j<8时直接终止循环,无法填充最后一行的前8个格子,应改为:
while not (i == 8 and j == 8):
修正后效果
修正后,回溯逻辑能正确回退到上一个可修改的位置并重置状态,数独棋盘可以完整填充到最后一个格子(8,8)。
内容的提问来源于stack exchange,提问作者Gayathri Sahana
相关产品推荐
相关产品推荐

