軟工個人專案-3.數獨問題
經過查閱資料,目前的數獨終局生成方法大體分為回溯法線上生成 和 根據種子數獨變換得到。數獨的解題方法主要分為 回溯法和 基於規則的方法。
數獨終局生成
回溯法
https://medium.com/@rossharrison/generating-sudoku-boards-pt-1-structures-algorithms-a1e62feeb32
沒什麼好說的,從坐上到右下依次填合法的數字,失敗就回退。
這個連結主要是使用各種STL庫改進了效率的問題。
回溯法可以通過每次選數填入的隨機性來做到隨機生成數獨,這是變換法不能做到的。
回溯法有多種改進方法:
- 一次填一個數字
- 先隨機填寫中心的宮,稍微減少一些問題規模再回溯(我在想隨機填寫對角線三個宮是否能保證有解,不過目前還沒有想法)
變換法
找到種子數獨,然後使用各種變換製造新的數獨
- 1~9數字的置換
- 旋轉0,90,180,270角度
- 正反面翻轉
- 同宮的行列交換
這種辦法比回溯法速度要快。
數獨解題演算法
回溯法
沒什麼好說的,相當於生成演算法從已經有結果的狀態開始執行。
基於規則的方法
搜尋StackOverflow,這個norvig的方法貌似非常火爆。而且直覺上比回溯法可能更有效率一些,因為它基於規則進行剪枝。
簡而言之,每個格子有一些備選數字的集合,求解的操作就是根據刪除規則(基於人的推理過程)其中的元素直到只剩下一個確定解為止。
刪除元素的時候是遞迴操作的,刪除操作的影響可能使其他格子也滿足刪除條件:
(1) If a square has only one possible value, then eliminate that value from the square's peers.
(2) If a unit has only one possible place for a value, then put the value there.
這個過程叫Constraint Propagation。
當刪無可刪的時候,進行深度優先搜尋。但是因為深搜的同時也用規則,所以對原局面破壞的很嚴重,於是作者放棄回溯的“保護現場”,而選擇為每個分支直接複製一份盤面使用。
其他參考資料:
http://www.cnblogs.com/kaige/p/sudok_algorithms.html
https://blog.csdn.net/Xcodingman/article/details/80639788
https://blog.csdn.net/qq_26822029/article/details/81129701
https://blog.csdn.net/nibiewuxuanze/article/details/47679927