基于python_深度优先搜索初体验_解决数独问题_1.25

数独问题描述(摘自百度百科)
数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。

程序思路

找出数独中所有未填数的位置,顺序从左往右,从上到下;之后得到某个位置横,竖,3*3方格中所有已经存在的数字,通过排除法得到这个空格能填什么数字;如果这个空格什么都填不了,则排除上一个空格已有的数字,填入下一个可以填入的数字

值得一提的是,如果这个数独无解程序会报错,因为实在懒得写这个了。。。

程序如下

#L为数独,可更改
#L0为空(0)的位置,不可更改
#L_visited 表示来过这个空
#Lnot为某个空不能填的数字
#L_yes列表套列表,指某个空可以填的数字,从第一个开始;如果指向空列表,则返回上一个访问地址,并且消除第一个数字
#数独输入格式如下
L = [[0,0,8,2,0,0,0,0,5],
     [0,3,0,0,0,0,0,0,0],
     [0,0,9,0,0,6,0,1,0],
     [5,0,0,9,0,0,0,0,3],
     [0,0,4,0,0,7,6,0,0],
     [3,0,0,0,0,0,0,0,1],
     [0,9,0,8,0,0,3,0,0],
     [0,0,0,0,0,0,0,7,0],
     [2,0,0,0,0,4,9,0,0]]
#得到L0的函数
def find_0(L):
    L0 = []
    for i in range(9):
        for j in range(9):
            if L[i][j]==0:
                L0.append((i,j))
    return L0

L0 = find_0(L)

L_yes = [[] for ha in range(len(L0))]

L_visited = [0 for i in range(len(L0))]

#初始指针 = 0
zhizhen = 0

while True:   
    print(L)

if zhizhen==len(L0):break
a,b = L0[zhizhen]
if L_visited[zhizhen] == 0:
    L_visited[zhizhen] = 1
    Lnot = []
    for i in range(9):
        if L[a][i] not in Lnot:Lnot.append(L[a][i])
    for j in range(9):
        if L[j][b] not in Lnot:Lnot.append(L[j][b])

    # small_square()
    if a<=2 and b<=2:
        for i0 in range(3):
            for j0 in range(3):
                if L[i0][j0] not in Lnot: Lnot.append(L[i0][j0])
    if a<=2 and 3<=b<=5:
        for i0 in range(3):
            for j0 in range(3,6):
                if L[i0][j0] not in Lnot: Lnot.append(L[i0][j0])
    if a<=2 and 6<=b<=8:
        for i0 in range(3):
            for j0 in range(6,9):
                if L[i0][j0] not in Lnot: Lnot.append(L[i0][j0])
    if 3<=a<=5 and b<=2:
        for i0 in range(3,6):
            for j0 in range(3):
                if L[i0][j0] not in Lnot: Lnot.append(L[i0][j0])
    if 3<=a<=5 and 3<=b<=5:
        for i0 in range(3,6):
            for j0 in range(3,6):
                if L[i0][j0] not in Lnot: Lnot.append(L[i0][j0])
    if 3<=a<=5 and 6<=b<=8:
        for i0 in range(3,6):
            for j0 in range(6,9):
                if L[i0][j0] not in Lnot: Lnot.append(L[i0][j0])
    if 6<=a<=8 and b<=2:
        for i0 in range(6,9):
            for j0 in range(3):
                if L[i0][j0] not in Lnot: Lnot.append(L[i0][j0])
    if 6<=a<=8 and 3<=b<=5:
        for i0 in range(6,9):
            for j0 in range(3,6):
                if L[i0][j0] not in Lnot: Lnot.append(L[i0][j0])
    if 6<=a<=8 and 6<=b<=8:
        for i0 in range(6,9):
            for j0 in range(6,9):
                if L[i0][j0] not in Lnot: Lnot.append(L[i0][j0])
    for hei in range(1,10):
        if hei not in Lnot:L_yes[zhizhen].append(hei)
try:   
    L[a][b] = L_yes[zhizhen][0]
except IndexError: #搜索所有的可能性都失败后返回上一层
    L_visited[zhizhen] = 0
    L[a][b] = 0
    L_yes[zhizhen-1] = L_yes[zhizhen-1][1:]
    zhizhen = zhizhen-1
else:zhizhen = zhizhen+1

print(L)

测试结果
大概试了某网站上10多个困难++难度的题目(测10多个很不负责任的说,但是我太懒了。。。),时间上最长的一个跑了4-5分钟,准确答案都能跑出来

注释很乱求轻喷QAQ,以后可能会找时间优化(咕咕咕)

感悟
为什么别人家的代码都这么优美QAQ,函数清楚,逻辑清晰。我打算明天再写一个好看一点的QWQ(我觉得以后这样写程序会被同事打的。。。)

你可能感兴趣的:(基于python_深度优先搜索初体验_解决数独问题_1.25)