【问题标题】:Sudoku solver in python using backtrackingpython中的数独求解器使用回溯
【发布时间】:2016-12-14 01:29:07
【问题描述】:

我看到了一些数独求解器的实现,但我无法在我的代码中找出问题所在。我有一个函数 sudokusolver,它变成了数独板并且必须返回已解决的数独板。

def sudokutest(s,i,j,z):
    # z is the number
    isiValid = np.logical_or((i+1<1),(i+1>9));
    isjValid = np.logical_or((j+1<1),(j+1>9));
    iszValid = np.logical_or((z<1),(z>9));
    if s.shape!=(9,9):
        raise(Exception("Sudokumatrix not valid"));
    if isiValid:
        raise(Exception("i not valid"));
    if isjValid:
        raise(Exception("j not valid"));
    if iszValid:
        raise(Exception("z not valid"));

    if(s[i,j]!=0):
        return False;

    for ii in range(0,9):
        if(s[ii,j]==z):
            return False;

    for jj in range(0,9):
        if(s[i,jj]==z):
            return False;

    row = int(i/3) * 3;
    col = int(j/3) * 3;
    for ii in range(0,3):
        for jj in range(0,3):
            if(s[ii+row,jj+col]==z):
                return False;

    return True;

def possibleNums(s , i ,j):
    l = [];
    ind = 0;
    for k in range(1,10):
        if sudokutest(s,i,j,k):
            l.insert(ind,k);
            ind+=1;
    return l;

def sudokusolver(S):
    zeroFound = 0;
    for i in range(0,9):
        for j in range(0,9):
            if(S[i,j]==0):
                zeroFound=1;
                break;
        if(zeroFound==1):
            break;
    if(zeroFound==0):
          return S;

    x = possibleNums(S,i,j);
    for k in range(len(x)):
        S[i,j]=x[k];
        sudokusolver(S);
    S[i,j] = 0;
    sudokusolver(S);
    return S;

sudokutest 和 possibleNums 是正确的,只有 sudokusolver 给出 RecursionError

【问题讨论】:

    标签: python artificial-intelligence sudoku


    【解决方案1】:

    除了回溯递归搜索之外,您还可以通过使用一些启发式算法(例如最少剩余值启发式算法)和约束传播技术(例如前向检查和弧一致性)来减少要分配的变量的域,方法是确保一致性。

    以下动画显示了一个示例数独难题解决方案,其中包含所有启发式和约束传播,从而使递归 BT 搜索更快。

    输入

    使用 AC-3 / BT 和 RMV 启发式 / 前向检查的 Sudoku 求解器的最后几个步骤(BT 搜索总共需要 369 个步骤才能找到解决方案,它返回的速度非常快,找到解决方案的总时间 ~ 2秒)

    这是回溯树的一部分:

    详情可以参考https://sandipanweb.wordpress.com/2017/03/17/solving-sudoku-as-a-constraint-satisfaction-problem-using-constraint-propagation-with-arc-consistency-checking-and-then-backtracking-with-minimum-remaning-value-heuristic-and-forward-checking/?frame-nonce=9d28c0c035

    【讨论】:

      【解决方案2】:

      在最后三行:

      S[i,j] = 0;
      sudokusolver(S);
      return S;
      

      您总是重置更改,因此 S 永远不会被填充。最后的递归应该是不需要的。

      【讨论】:

      • 我试过 x = possibleNums(S,i,j);对于范围内的 k(len(x)): S[i,j]=x[k];返回数独求解器(S); S[i,j] = 0;返回 S;但对于困难的数独,它会停止
      • 我认为这不会有帮助
      • @SHristoskov,您尝试过还是只是假设它不起作用?
      • 是的,我确定。也许对于简单的数独会起作用,但对于困难的数独则不行
      猜你喜欢
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 2014-02-07
      • 2017-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多