1. 程式人生 > >軟工個人專案-3.數獨問題

軟工個人專案-3.數獨問題

經過查閱資料,目前的數獨終局生成方法大體分為回溯法線上生成 和 根據種子數獨變換得到。數獨的解題方法主要分為 回溯法和 基於規則的方法。

數獨終局生成

回溯法

https://medium.com/@rossharrison/generating-sudoku-boards-pt-1-structures-algorithms-a1e62feeb32

沒什麼好說的,從坐上到右下依次填合法的數字,失敗就回退。

這個連結主要是使用各種STL庫改進了效率的問題。

回溯法可以通過每次選數填入的隨機性來做到隨機生成數獨,這是變換法不能做到的。

回溯法有多種改進方法:

  • 一次填一個數字
     一般可以避免過早進入死衚衕
  • 先隨機填寫中心的宮,稍微減少一些問題規模再回溯(我在想隨機填寫對角線三個宮是否能保證有解,不過目前還沒有想法)

變換法

找到種子數獨,然後使用各種變換製造新的數獨

  • 1~9數字的置換
  • 旋轉0,90,180,270角度
  • 正反面翻轉
  • 同宮的行列交換

這種辦法比回溯法速度要快。

數獨解題演算法

回溯法

沒什麼好說的,相當於生成演算法從已經有結果的狀態開始執行。

基於規則的方法

http://norvig.com/sudoku.html

搜尋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