[buaa-SE-2017]我的項目

我的項目


Part1:github

https://github.com/Aria-K-Alethia/Sudokuhtml


Part2:解題思路描述

關於數獨的解法

我選擇的是暴力搜索算法。c++

(1)關於 -c
首先,本題要求生成的數獨最多爲1,000,000個,而且要生成的數獨都是9x9規模的,而並非nxn規模,再加上數獨自己的限制能夠實現必定程度上的剪枝,所以暴力搜索是可行的。git

另外一方面,本題須要生成的數獨各不相同,暴力搜索能夠搜索全部的可行解,很容易實現不重複的要求,因此最終我選擇暴力搜索的方法。github

(2)關於-s
暴力搜索在解決數獨的時候只須要搜索到一個解就能夠,雖然對於一些遞歸層數比較深的數獨會有些乏力,不過整體上也能夠接受。算法

關於其餘解法

我在分析的題目時候查找了其餘的解法,包括dancing link、分治,可是dancing link的複雜度較高(參看算法實踐——舞蹈鏈(Dancing Links)算法求解數獨),且其實現複雜,因此不使用。數組

分治的方法將9x9盤面分紅9個3x3的盤面,每次在每一個盤面上生成數字,這個和普通的回溯法實際是相似的,因此效率應該也相似(關於效率參看【算法研究】數獨高效徹底解生成算法的研究和實現),並且最後我用暴力法實現以後也證實了這一點。性能


Part3:設計實現過程

關於設計

個人設計比較簡單,整個程序分爲3個類:單元測試

  • InputHandler:處理和分析輸入。
  • Sudoku:處理全部數獨相關操做。
  • Output:處理全部錯誤輸出。

程序的流程就是由InputHandler處理輸入,而後Sudoku根據不一樣的指令來解決,若是這個過程當中有什麼錯誤發生則會由Output響應。學習

關於測試

測試中,首先測試了基本功能,而後針對一些邊界值(好比空文件和生成0個數獨)進行了測試。
在性能改進以後,又進行了迴歸測試。
測試初始化:

這裏設置了相關參數測試

下圖是其中一個測試單元:

這個測試單元測試了

bool get_board(fstream &file,char board[][LEN+1])

這個方法從file文件中讀入一個數獨,成功則返回true,若是數獨的行數不夠則返回false,咱們首先讀入一個正確的數獨,而後在文件中輸入錯誤信息以後從新測試,這時outcome變量應該是false。


Part4:性能分析和改進

我在性能改進上大概花費了3個小時的時間。
最初我使用了c++的內置類string來處理輸出,可是性能分析以後發現速度太慢,輸出1million個須要1分鐘,因此我針對這一點以及I/O輸出進行了優化,具體體如今:

  • 替換string轉而使用char*來處理字符串
  • 將全部結果存儲在一個大數組中,最後直接輸出全部結果,而不是每次輸出一個數獨終局。

以後程序在I/O上已經不花費太多的時間,根據性能分析圖能夠看到,大部分的時間都集中在回溯搜索上:


Part5:關鍵代碼

回溯部分代碼:

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),若是能就插入而後繼續遞歸。


Part6:PSP表

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

Part7:總結

因爲我以前沒有學過C++,因此此次在技術學習上花費了不少時間,致使最後沒有太多的時間來coding,因此我的以爲此次代碼的質量並不太好。 不過此次也有不少收穫,能初步運用C++、學了VS這個超強大IDE。

相關文章
相關標籤/搜索