天天看點

用python解數獨_python解數獨

python 解數獨

一、數獨規則:

\qquad數獨共有九九八十一個小方格,要求每一行、每一列的小方格都包含數字1-9,且不能重複;将這個方格平均分成9個3 ∗

*∗ 3的方格,每個方格的數字也必須包含1-9,且不能重複。

二、解題思路

\qquad 1、擷取每一個空缺方格的坐标;

\qquad 2、周遊每一個空缺方格的坐标進行取可能的值,周遊從1-9進行取值。

\qquad(1)若滿足數字不包含在空缺坐标的所在行和所在列以及3 ∗

*∗ 3方格内,則停止周遊,将該數字指派于空缺坐标内;

\qquad(2)、若1-9都包含在空缺坐标的所在行和所在列以及3 ∗

*∗ 3方格内,則傳回上一步,從比上一步的取值大1開始周遊取值。

三、代碼

import pandas as pd

import time

class Sudoku():

def __init__(self,data):

self.data = data

# 擷取空缺坐标

self.origin_list = [[i,j] for i in range(9) for j in range(9) if data.iloc[i,j]==0]

# 判斷小格子屬于哪個小正方形,并讀取該小正方形的資料

def Check_in(self,i,j):

a = i//3

b = j//3

data = self.data.iloc[a*3:a*3+3,b*3:b*3+3]

data = data.values.flatten()

return data

# 判斷小格子數字的值

def Check_Value(self,num,i,j):

for a in range(num,10):

if (a not in list(self.data.iloc[i,:]))&(a not in list(self.data.iloc[:,j]))&(a not in self.Check_in(i,j)) :

b=a

else:

b=0

if b!=0:

break

return b

# 傳回上一步

def Come_Back(self,i):

i = i - 1

while True:

# 擷取上一步的取值,并對取值進行加1

num = self.data.iloc[self.origin_list[i][0],self.origin_list[i][1]]+1

# 若上一步取值為9,則對上一步的格子指派0,然後再往前退一步

if num >9:

self.data.iloc[self.origin_list[i][0],self.origin_list[i][1]] = 0

i= i-1

# 若傳回上一步周遊後沒有數值可取,則對上一步的格子指派0,然後再傳回上一步

elif self.Check_Value(num,self.origin_list[i][0],self.origin_list[i][1])==0:

self.data.iloc[self.origin_list[i][0], self.origin_list[i][1]] = 0

i = i - 1

# 若傳回上一步周遊可以取得滿足條件的值,則計算出該值,并退出循環

else:

a = self.Check_Value(num,self.origin_list[i][0],self.origin_list[i][1])

break

c = [a,i]

return c

# 判斷每個格子的值

def Value_In(self):

i = 0

num = 1

while True:

# 對空缺值進行取值

a = self.Check_Value(num, self.origin_list[i][0], self.origin_list[i][1])

# 若該格子能取到滿足條件的值,則對該格子進行指派,并進入下一個空缺格子,取值函數的取值範圍是0-9,則大于0即為滿足條件

if a >0:

self.data.iloc[self.origin_list[i][0],self.origin_list[i][1]] = a

i+=1

# 若該格子無法取得滿足條件的值,則傳回上一步。

else:

c = self.Come_Back(i)

i = c[1]

self.data.iloc[self.origin_list[i][0],self.origin_list[i][1]] = c[0]

i=i+1

# 當所有空缺格子都填滿了則退出循環

if i>=len(self.origin_list):

break

return

def main():

# 讀取資料

data = pd.read_excel('./sudoku.xlsx', header = None, names = [str(i) for i in range(9)])

# 對空缺的數值指派為0

data = data.fillna(0)

# 對所有的資料類型改為整數型

data = data.astype(int)

start = time.clock()

sudoku = Sudoku(data)

sudoku.Value_In()

end = time.clock()

print(sudoku.data)

print(end-start)

if __name__ == "__main__":

main()

原文連結:https://blog.csdn.net/vgrant/article/details/108974369