python中数独的回溯算法

Posted

技术标签:

【中文标题】python中数独的回溯算法【英文标题】:Backtracking algorithm for Sudoku in python 【发布时间】:2020-05-15 15:10:44 【问题描述】:

我正在尝试使用回溯来制作数独求解器。当我手动处理代码时,它工作得很好,但是当我运行它时,我的返回解决方案中出现了空单元格。我花了如此多的时间试图修复它,但我什至无法弄清楚它到底哪里出了问题。我相当肯定我检查细胞溶液的功能是正确的。代码如下:

import numpy as np

board = np.array([[0, 0, 0, 8, 4, 0, 0, 0, 3],
                  [0, 7, 5, 0, 0, 0, 0, 0, 0],
                  [0, 4, 3, 0, 0, 6, 0, 0, 0],
                  [0, 0, 7, 0, 0, 8, 4, 9, 0],
                  [0, 0, 0, 9, 3, 1, 0, 0, 0],
                  [0, 5, 2, 7, 0, 0, 8, 0, 0],
                  [0, 0, 0, 2, 0, 0, 3, 4, 0],
                  [0, 0, 0, 0, 0, 0, 6, 2, 0],
                  [2, 0, 0, 0, 7, 3, 0, 0, 0]])

#check if input is viable solution for a cell
def isSolution(row, col, n):
    #return 0 for false (not a possible solution)
    #return 1 for true (possible solution)
    a = 0
    for i in range(0,9):
        if(board[row,i] == n):
            a += 1
        if(board[i,col] == n):
            a += 1
    h = (1 - (2 * ((row % 3) != 0)))
    i = (1 - (2 * ((col % 3) != 0)))
    j = (2 - (row % 3)**2)
    k = (2 - (col % 3)**2)
    if(board[row + h, col + i] == n):
        a += 1
    elif(board[row + h, col + k] == n):
        a += 1
    elif(board[row + j, col + i] == n):
        a += 1
    elif(board[row + j, col + k] == n):
        a += 1
    if(a == 0):
        return 1
    else:
        return 0

def solve():
    for row in range(0, 9):
        for col in range(0,9):
            if(board[row,col] == 0):
                for n in range(1, 10):
                    if(isSolution(row, col, n) == 1):
                        board[row,col] = n
                        print(board)
                        solve()
                        board[row,col] = 0

                return


#main
solve()

如果可以,请提供帮助

【问题讨论】:

请注意,您应该返回 TrueFalse 而不是 0 或 1,并且当您发现不兼容时,您不需要增加 a:只需立即返回 False,然后如果您设法到达该点,请在函数结束时返回 True 你永远不会测试你是否找到了解决方案(当你到达最内层循环的末尾时 col == row == 8),所以你找到它,然后继续尝试其他解决方案。 嵌套列表可能与数组一样快或更快,因为您正在索引单个元素。还要密切注意板是在原地修改还是复制。 【参考方案1】:

Thierry Lathuille 的扩展评论

def solve():
    for row in range(0, 9):
        for col in range(0,9):
            if(board[row,col] == 0):
                for n in range(1, 10):
                    if(isSolution(row, col, n) == 1):
                        board[row,col] = n
                        # print(board)
                        if (board != 0).all():
                            raise StopIteration
                        solve()
                        board[row,col] = 0

                return


#main
try:
    solve()
except StopIteration:
    print(board)

【讨论】:

非常感谢,这是完美的!

以上是关于python中数独的回溯算法的主要内容,如果未能解决你的问题,请参考以下文章

数独1--暴力回溯法(时间超)

为啥我使用回溯解决数独的 JAVA 代码没有给出任何解决方案? [关闭]

Python数独回溯

20191030-带返回值的回溯算法Leetcode解数独

数独回溯算法

保存结果数独回溯