python演算法之利用回溯演算法解數獨

2021-10-07 14:14:36 字數 2929 閱讀 3017

小明最近對數獨著迷,在玩遊戲的時候,電腦程式能夠立刻的出答案,好奇的它想知道計算機是怎麼得出結果的。數獨的遊戲規則是根據盤面上的已知數字推理出空格裡的數字,要求每一行、每一列、每乙個粗線格中均含1~9,且不重複。

面對這樣的問題,沒有像公式一樣的直接解決方式,所以只能靠嘗試。就像在走迷宮,沒有地圖沒所以面對每乙個岔路口都只能以探索的形式深入,一旦發現路線不對就返回岔路口,選擇另乙個分支。

把這個比喻用在數獨上的話,每乙個空格就是乙個岔路口,而每乙個岔路口都有9種選擇。我們肯定末端有乙個出口。那麼從第乙個岔路口出發。假設第1各空格種的數字:1不可以,2也不可以,3可以。

接下來假設第二個空格,1、2、3都不可以,4可以。

這樣一直假設下去,如果盤面上的數字相互矛盾則改變上一格的數字,在次嘗試,當我們到達最後乙個空格並且成功填入數字時,即可輸出答案。

數獨解題思路圖:

注意:每一次假設後都要把格仔還原回0,以便下一次假設時盤面上的數字不衝突。如果不歸零,那麼可能陷入死局後退回到第乙個空格時,第二個空格裡已經有了9,這會影響我們的判斷。

最終**:

class

solution()

:def

solvesudoku

(self,board)

: self.helper(board,0)

defhelper

(self,board,index)

:if index >=81:

#如果盤面已滿

self.printsolution(board)

#輸出結果

return

#返回上一格

if board[index]==0

:#如果當前格為空格

for i in

range(1

,10):

#依次假設1~9

if self.isvalid(board,index,i)

:#如果假設成立

board[index]

= i #填入數字

self.helper(board,index +1)

#繼續假設

board[index]=0

else

:#如果當前格有已知數

self.helper(board,index +1)

#跳過此格

defprintsolution

(self,board)

:#輸出結果

for i in

range(0

,81,9

):print

(board[i:i+9]

)def

isvalid

(self,board,index,num)

:#isvalid方法檢查當前假設是否合理

row = index //

9#當前格仔的行數

column = index %

9#當前格仔的列數

for i in

range

(index +9,

81,9)

:#檢查和同列(下方)的格仔是否矛盾

if board[i]

== num:

return

false

for i in

range

(index -9,

-1,-

9):#檢查和同列(上方)的格仔是否矛盾

if board[i]

== num:

return

false

for i in

range(9

* row,9*

(row +1)

):#檢查和同行的格仔是否矛盾

if board[i]

== num:

return

false

for i in

range

(row - row %3,

3+ row - row %3)

:#檢查和同粗線格仔是否矛盾

for j in

range

(column - column %3,

3+ column - column %3)

:if board[j + i *9]

== num:

return

false

return

true

solution(

).solvesudoku([4

,1,0

,0,0

,7,8

,5,0

,8,0

,6,0

,0,0

,0,0

,9,0

,2,0

,0,9

,0,6

,0,0

,0,0

,4,0

,0,0

,0,1

,2,2

,0,0

,5,8

,0,0

,7,0

,0,0

,0,0

,0,0

,5,0

,0,0

,0,0

,7,0

,2,0

,0,0

,0,0

,8,0

,1,0

,0,0

,0,0

,7,0

,0,6

,0,0

,0,0

])

用回溯遞迴演算法解決走迷宮問題

迷宮是由許多小方格構成的矩形,在每個小方格中有的是牆,有的是路,走迷宮就是從乙個小方格沿上下左右四個方向到臨近的方格,當然不能穿牆。設迷宮的入口是在左上角 1,1 出口是右下角 8,8 根據給定的迷宮,找出一條從入口到出口的路徑。演算法設計思路 從入口開始廣度優先搜尋所有可到達的方格入隊,再擴充套件...

使用回溯演算法解決 0 1 揹包問題

對於 0 1 揹包問題,我們最高效的方法是使用動態規劃來解決,但其實我們使用回溯演算法也可以解決0 1揹包問題 問題描述 我們有乙個揹包,揹包可承載的重量是wkg。現在我們有n個物品,每個物品的重量不等,並且不可分割,我們現在期待選擇幾件物品裝載到揹包中,在不超過揹包重量的前提下如何讓揹包中物品的總...

演算法之 回溯演算法 詳解 python

回溯演算法實際上 基於dfs 深度優先搜尋 的乙個類似列舉的搜尋嘗試過程,主要是在搜尋嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就 回溯 返回到上乙個狀態,嘗試其他的路徑,這種走不通就退回再走的技術為回溯法 滿足回溯條件的某個狀態的點稱為 回溯點 dfs 和回溯演算法區別 dfs 是乙個勁的...