python deepcopy函数_用Python解数独[6]:递归获得最终答案
生活随笔
收集整理的這篇文章主要介紹了
python deepcopy函数_用Python解数独[6]:递归获得最终答案
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
[2][1] 解決數獨問題基本思路
7、遞歸獲得最終答案
上一回我們對于值域列表縮減函數進行了改造,增加了檢測唯一值的方法,但最終我們依然沒有得到答案,還有很多單元格的答案沒有確定,應該怎么辦呢?
在當前這種情況下,我們已經無法從數獨中直接確定某個單元格的答案了,但是我們可以用試驗的辦法,去驗證某個單元格的答案是值域里的哪一個值。我們以第7行第7列單元格為例,我們假設它的值是1,則這個變化會引起一系列的變化,最終我們得到這個:
在第二個九宮格出現了2個7,因此我們可以判斷第7行第7列的值不是1,而應該是6。我們通過這種測試驗證的方法獲得了某個單元格的答案。我們現在需要用代碼來實現:
# 主函數,輸入值域列表,如遇到多個取值的單元格,依次嘗試值域里的每個值,通過遞歸的方法檢測值是否正確這段代碼其實還是挺復雜的,容我細細解讀:
# 主函數,輸入值域列表,如遇到多個取值的單元格,依次嘗試值域里的每個值,通過遞歸的方法檢測值是否正確- 我們設置i和j兩個循環,是為了遍歷total_value_range里的每一個元素
- 當len(total_value_range[i][j]) = 1時,也就是說這個單元格是已知單元格,取值已經確定了;如果len(total_value_range[i][j]) > 1,這個單元格是未知單元格,值域列表有多個取值;
- 對于未知單元格,我們遍歷它的值域,同時拷貝一份total_value_range,并把值域里的值賦給test_value[i][j],開始進行“試驗”,看test_value[i][j]里的哪一個值是正確的;
- 賦值之后,我們立即使用之前的generator_soduku()和reduce_totalValueRange()方法,基于已有條件生成一個最新的值域列表;
- 然后我們需要做的是,用soduku_checkRepeat()方法檢驗當前的值域列表是否合法,soduku_checkRepeat()方法的原理也很簡單:
- 首先我們寫出一個檢查行值域列表是否合法的函數:將一行已知單元格都選出放到一個列表里,檢查列表是否有重復值;
- 有了行值域檢查函數,只需將數獨進行行列轉換和九宮格轉換然后分別進行檢測,如果三項檢測均為True,則最后返回True,有一項False,最后返回False
- 如果soduku_checkRepeat()顯示當前值域列表合法,則使用sodukuRate()方法檢測當前值域列表每個單元格是否都是已知單元格(各單元格值域長度均為1)
- 若每個單元格值域長度均為1,則說明已經得到最終正確答案,則返回test_value,即最終正確答案;
- 若sodukuRate(test_value)不為1,則說明經過一番操作后還未得到正確答案,或者得到錯誤答案,因此我們將當前的值域列表test_value作為參數,用if判斷trial(test_value),這個就用上了遞歸的概念,我們稍后詳細解釋;
- 如果soduku_checkRepeat()顯示當前值域列表不合法,則說明total_value_range[i][j]當前的取值k不正確,我們continue,繼續循環;
- 如果for k in total_value_range[i][j],這個循環結束了,說明所有的取值k都是導向錯誤的結果(在第一層trial()是不會出現的,會出現在第二層trial()時),則返回False;
最終運行代碼,得到了結果
PS把全部源碼展示出來:
import下一期我們將詳細解釋這個利用了遞歸的函數,具體是如何運行的,我們這個用Python解數獨欄目也將迎來尾聲。
下一篇鏈接:用Python解數獨[7]:遞歸(完結篇)
總結
以上是生活随笔為你收集整理的python deepcopy函数_用Python解数独[6]:递归获得最终答案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一面积等于多少?
- 下一篇: 4款儿童衣柜推荐白色粉色的干净世界