Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
589 views
in Technique[技术] by (71.8m points)

artificial intelligence - Sudoku solver in python using backtracking

I saw a few sudoku solvers implementations ,but I cant figure out the problem in my code. I have a function sudokusolver which becomes sudoku Board and must return solved sudoku board.

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 and possibleNums are correct , only sudokusolver give a RecursionError

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Along with backtracking recursive search, you could also improve your algorithm by using some heuristics such as least remaining value heuristic and constraint propagation techniques such as forward checking and arc-consistency to reduce the domain of the variables to be assigned, by ensuring consistency.

The following animation shows an example Sudoku puzzle solution with all the heuristics and constraint propagation, thereby making the recursive BT search much faster.

Input

enter image description here

Last few steps of the Sudoku solver with AC-3 / BT with RMV heuristic / forward checking (it takes total 369 steps for the BT search to find a solution and it returns pretty fast, total time to find the solution ~ 2 secs)

enter image description here

Here is part of the backtracking tree:

enter image description here

For details you may want to refer to 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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...