https://github.com/Aria-K-Alethia/Sudokuhtml
我選擇的是暴力搜索算法。c++
(1)關於 -c
首先,本題要求生成的數獨最多爲1,000,000個,而且要生成的數獨都是9x9規模的,而並非nxn規模,再加上數獨自己的限制能夠實現必定程度上的剪枝,所以暴力搜索是可行的。git
另外一方面,本題須要生成的數獨各不相同,暴力搜索能夠搜索全部的可行解,很容易實現不重複的要求,因此最終我選擇暴力搜索的方法。github
(2)關於-s
暴力搜索在解決數獨的時候只須要搜索到一個解就能夠,雖然對於一些遞歸層數比較深的數獨會有些乏力,不過整體上也能夠接受。算法
我在分析的題目時候查找了其餘的解法,包括dancing link、分治,可是dancing link的複雜度較高(參看算法實踐——舞蹈鏈(Dancing Links)算法求解數獨),且其實現複雜,因此不使用。數組
分治的方法將9x9盤面分紅9個3x3的盤面,每次在每一個盤面上生成數字,這個和普通的回溯法實際是相似的,因此效率應該也相似(關於效率參看【算法研究】數獨高效徹底解生成算法的研究和實現),並且最後我用暴力法實現以後也證實了這一點。性能
個人設計比較簡單,整個程序分爲3個類:單元測試
程序的流程就是由InputHandler處理輸入,而後Sudoku根據不一樣的指令來解決,若是這個過程當中有什麼錯誤發生則會由Output響應。學習
測試中,首先測試了基本功能,而後針對一些邊界值(好比空文件和生成0個數獨)進行了測試。
在性能改進以後,又進行了迴歸測試。
測試初始化:
這裏設置了相關參數測試
下圖是其中一個測試單元:
這個測試單元測試了
bool get_board(fstream &file,char board[][LEN+1])
這個方法從file文件中讀入一個數獨,成功則返回true,若是數獨的行數不夠則返回false,咱們首先讀入一個正確的數獨,而後在文件中輸入錯誤信息以後從新測試,這時outcome變量應該是false。
我在性能改進上大概花費了3個小時的時間。
最初我使用了c++的內置類string來處理輸出,可是性能分析以後發現速度太慢,輸出1million個須要1分鐘,因此我針對這一點以及I/O輸出進行了優化,具體體如今:
以後程序在I/O上已經不花費太多的時間,根據性能分析圖能夠看到,大部分的時間都集中在回溯搜索上:
回溯部分代碼:
for (int k = 1; k <= LEN; ++k) { if (Sudoku::count >= n) return; //if generate enough sudoku,return if (check_generate_pos(i, j, k)) { //check if it is ok to set k on (i,j) board[i][j] = k + '0'; trace_back_n(i, j + 1, n, file); //if can,recur to next place } }
遍歷全部可能的數字,首先檢查生成的數獨是否足夠,若是足夠就返回,不足夠就檢查當前數字可否插入位置(i,j),若是能就插入而後繼續遞歸。
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
Planning | 計劃 | 30 | 20 |
· Estimate | · 估計這個任務須要多少時間 | 5 | 5 |
Development | 開發 | 60 | 60 |
· Analysis | · 需求分析 (包括學習新技術) | 180 | 480 |
· Design Spec | · 生成設計文檔 | 30 | 20 |
· Design Review | · 設計複審 (和同事審覈設計文檔) | 0 | 0 |
· Coding Standard | · 代碼規範 (爲目前的開發制定合適的規範) | 5 | 0 |
· Design | · 具體設計 | 60 | 120 |
· Coding | · 具體編碼 | 120 | 180 |
· Code Review | · 代碼複審 | 60 | 180 |
· Test | · 測試(自我測試,修改代碼,提交修改) | 60 | 60 |
Reporting | 報告 | 30 | 30 |
· Test Report | · 測試報告 | 30 | 30 |
· Size Measurement | · 計算工做量 | 5 | 5 |
· Postmortem & Process Improvement Plan | · 過後總結, 並提出過程改進計劃 | 30 | 30 |
Total | 合計 | 705 | 1220 |
因爲我以前沒有學過C++,因此此次在技術學習上花費了不少時間,致使最後沒有太多的時間來coding,因此我的以爲此次代碼的質量並不太好。 不過此次也有不少收穫,能初步運用C++、學了VS這個超強大IDE。