软件工程基础课-个人项目-数独
- 一、項(xiàng)目地址
- 二、PSP
- 三、解題思路
- 四、設(shè)計(jì)實(shí)現(xiàn)過程
- 4.1 代碼風(fēng)格規(guī)范
- 4.2 函數(shù)關(guān)系圖
- 五、程序性能分析及改進(jìn)
- 六、代碼說明
- 七、單元測(cè)試與代碼覆蓋率分析
- 八、項(xiàng)目總結(jié)
- 8.1 個(gè)人的提升
- 8.2 不足
- 致謝
一、項(xiàng)目地址
代碼托管在了GitHub上,地址:https://github.com/InspAlgo/Personal_Suduku
各位看官大大們記得給我項(xiàng)目點(diǎn)star,我請(qǐng)你們擼代碼!
還有個(gè)人項(xiàng)目紀(jì)實(shí)忠實(shí)記錄個(gè)人項(xiàng)目開發(fā)過程,有很多細(xì)節(jié)!
二、PSP
| Planning | 計(jì)劃 | ||
| ·Estimate | ·估計(jì)這個(gè)任務(wù)需要多長(zhǎng)時(shí)間 | 10 | 20 |
| Development | 開發(fā) | ||
| ·Analysis | ·需求分析(包括學(xué)習(xí)新技術(shù)) | 60 | 120 |
| ·Design Spec | ·生成設(shè)計(jì)文檔 | 300 | 120 |
| ·Design Review | ·設(shè)計(jì)復(fù)審(和同事審核設(shè)計(jì)文檔) | / | / |
| ·Coding Standard | ·代碼規(guī)范(為目前的開發(fā)制定合適的規(guī)范) | 120 | 180 |
| ·Design | ·具體設(shè)計(jì) | 120 | 180 |
| ·Coding | ·具體編碼 | 1080 | 1200 |
| ·Code Review | ·代碼復(fù)審 | 300 | 60 |
| ·Test | ·測(cè)試(自我測(cè)試,修改代碼,提交修改) | 300 | 960 |
| Reporting | 報(bào)告 | ||
| ·Test Report | ·測(cè)試報(bào)告 | 60 | 60 |
| ·Size Measurement | ·計(jì)算工作量 | 30 | 30 |
| ·Postmortem & Process Improvement Plan | ·事后總結(jié),并提出過程改進(jìn)計(jì)劃 | 180 | 120 |
| <script id="MathJax-Element-8" type="math/tex"> </script> | 合計(jì) | 2560 | 3050 |
三、解題思路
看老師的要求文檔,數(shù)獨(dú)?用計(jì)算機(jī)解數(shù)獨(dú)問題~還要啥代碼分析、性能測(cè)試?還要托管在github上,還要用git進(jìn)行版本控制,還有各種規(guī)范,還尼瑪各種數(shù)量巨多的要求。。。問題真是超級(jí)多啊!畢竟是個(gè)小工程項(xiàng)目。
不過總的來說有三個(gè)大塊:一是要搞定數(shù)獨(dú)求解算法,這個(gè)是核心;二是代碼測(cè)試、性能分析,與我們之前寫類似OJ的算法習(xí)題不同,這個(gè)是一個(gè)正式的軟件編程的必要部分;三是進(jìn)行版本管理以及項(xiàng)目規(guī)范,這是從項(xiàng)目工程角度指導(dǎo)設(shè)計(jì)及編寫代碼進(jìn)行軟件開發(fā)的,也是軟件工程學(xué)科的意義所在。在我看來這次個(gè)人項(xiàng)目考量的基本上是這三點(diǎn)了,接下來是具體步驟。
1. 首先有問題找搜索引擎,搜索數(shù)獨(dú) 計(jì)算機(jī) 算法等關(guān)鍵詞。這一步是要初步了解問題的樣子,先看看前人可有相關(guān)經(jīng)驗(yàn)可以借鑒,好讓心里有個(gè)譜,關(guān)鍵是了解是否有相關(guān)算法的存在。
在知乎上,我看這幾篇寫的很不錯(cuò):
數(shù)獨(dú)求解算法
暴力算法之美:如何在1毫秒內(nèi)解決數(shù)獨(dú)問題?| 暴力枚舉法+深度優(yōu)先搜索 POJ 2982
數(shù)獨(dú)求解算法Kotlin版
成為數(shù)獨(dú)高手有哪些好的訓(xùn)練方法
推薦的:
Solving Every Sudoku Puzzle
Sudoku solving algorithms
在谷歌、必應(yīng)上找的:
數(shù)獨(dú)高效完全解生成算法的研究和實(shí)現(xiàn)
算法實(shí)踐——舞蹈鏈(Dancing Links)算法求解數(shù)獨(dú)
跳躍的舞者,舞蹈鏈(Dancing Links)算法——求解精確覆蓋問題
[buaa-SE-2017]個(gè)人項(xiàng)目
算法:
2. 這里過程跳一下,在寫代碼前,我要先看看關(guān)于github和git的使用,因?yàn)橐笪臋n里說要看我們的commit情況,emmmm,這樣我就要先建倉庫啊,可這我也不會(huì)啊,于是又要找教程,這個(gè)也簡(jiǎn)單,隨便搜索一下就有入門教程,我也按教程先創(chuàng)了倉庫,具體可以看我的個(gè)人項(xiàng)目紀(jì)實(shí)。
3. 應(yīng)該講一講關(guān)于代碼測(cè)試與性能分析方面的了,不過考慮到這是項(xiàng)目后期問題,為了節(jié)省時(shí)間,我們先完成核心算法,先快速搞出項(xiàng)目原型,然后再來看這個(gè)問題,再一邊學(xué)一邊弄。
然后是關(guān)于具體算法的解題思路,看了那么多介紹數(shù)獨(dú)求解方法,感覺好多都看起來復(fù)雜度好高,還有隨機(jī)化方法的,不過個(gè)人感覺隨機(jī)化方法應(yīng)該是不可取的,因?yàn)槟銦o法判斷是否有重復(fù)的情況出現(xiàn),難不成又弄個(gè)哈希再檢測(cè)一下?那樣挺占用內(nèi)存的,畢竟壓力測(cè)試時(shí)可是有100萬的數(shù)據(jù)量;然后最直接的方法就是暴力回溯了,因?yàn)槲覀冎?~9這就九個(gè)數(shù)必定要出現(xiàn),那么生成終局問題就變成了給數(shù)字排位置問題,首先給九個(gè)1排,再給2排,再給3排……依次類推,最后排到9。每給一個(gè)數(shù)排好位置我們就要進(jìn)行遞歸,因?yàn)檫f歸操作很方便我們回溯,我們?cè)谂艛?shù)字時(shí),肯定會(huì)遇到排不了的情況,這時(shí)候我們就要返回上一步重新排數(shù)字,再不行就再返回。求解數(shù)獨(dú)的算法也基本相同,只不過只需要生成一個(gè)終局即可,我們可以把返回條件改為是否有解,因?yàn)椴皇撬械臄?shù)獨(dú)題都是有解的,也可能出現(xiàn)無解的情況,這個(gè)我現(xiàn)在無法確定所以不能忽略無解的情況。具體算法的偽代碼可參見我的個(gè)人項(xiàng)目紀(jì)實(shí)或者后面的代碼說明。
四、設(shè)計(jì)實(shí)現(xiàn)過程
4.1 代碼風(fēng)格規(guī)范
由于本部分內(nèi)容較多,故重新寫了篇博文,詳見軟件工程基礎(chǔ)課-個(gè)人項(xiàng)目-代碼風(fēng)格規(guī)范。
里面的內(nèi)容主要摘自Google C++風(fēng)格指南,同時(shí)在個(gè)人項(xiàng)目中盡力以此為風(fēng)格標(biāo)準(zhǔn),可能個(gè)別地方不一致。
4.2 函數(shù)關(guān)系圖
程序基本流程圖為:
Created with Rapha?l 2.1.2 開始 輸入指令 分析指令 求解數(shù)獨(dú) 輸出 結(jié)束 生成終局 yes no函數(shù)關(guān)系圖由VS自動(dòng)生成
五、程序性能分析及改進(jìn)
通過性能分析圖可以看出來我的檢查函數(shù)占比較多,因?yàn)槭潜┝厮菟悦恳徊蕉家袛嗍欠裼兄貜?fù)、不符合規(guī)則的數(shù)字出現(xiàn),而每次判斷都要用循環(huán)遍歷,這個(gè)就很耗時(shí)了,我是已經(jīng)作了優(yōu)化的,將橫豎分別循環(huán)判斷改成了同時(shí)循環(huán)判斷,emm,沒想到還是比較耗時(shí)間。還有一種方法就是加個(gè)位置記錄,具體方法是這樣,比如num_row[num][i]代表數(shù)字num在第i行是否有出現(xiàn),同理num_col[num][j]代表數(shù)字num在第j列是否有出現(xiàn),num_box[[num][row][col]代表數(shù)字num是否在第[row][col]小九宮格上有出現(xiàn)。這樣就不需要用循環(huán)判斷了,填數(shù)字了就賦值為false,剛開始沒數(shù)字時(shí)是賦值為true的。
然后試驗(yàn)了一下
如下圖可以看出C策略函數(shù)的檢查降到800的量級(jí),之前還是4000的量級(jí)
這次改進(jìn)還是有效果的,連檢查函數(shù)我都刪掉了,因?yàn)檫@種寫法的話判斷語句就太短了。不過需要注意的就是在合適的位置還原為true。
在基本完成程序后又重新進(jìn)行了一下性能分析,結(jié)果見下。
其中消耗最大的函數(shù)為strategyC,其具體情況為:
與之前性能分析比較有一定的時(shí)間延長(zhǎng),在本機(jī)測(cè)試時(shí)發(fā)現(xiàn)會(huì)出現(xiàn)一定的時(shí)間波動(dòng)。
六、代碼說明
我主要使用的是暴力回溯法生成數(shù)獨(dú)的,求解數(shù)獨(dú)同理。
我們看一下這個(gè)規(guī)則,會(huì)發(fā)現(xiàn)一個(gè)規(guī)律,就是第一行有數(shù)x后不能再有x,它一定會(huì)依次出現(xiàn)在后面的行,同理列也一樣,然后其他數(shù)也是這樣。那么我們?nèi)绻磾?shù)字順序在第一個(gè)小方格內(nèi)填入1,然后再在第二行某個(gè)格填入1,依次類推直到填完9種數(shù),到這里有人會(huì)說這樣遲早會(huì)產(chǎn)生沖突,出現(xiàn)不符合規(guī)則的局面,沒錯(cuò),的確會(huì)這樣,那么我們就從試不了的地方開始回溯,換個(gè)數(shù)繼續(xù)試,直到滿足位置,這里有時(shí)候會(huì)回溯好幾步才能成功,不過計(jì)算機(jī)比較快,尤其是用遞歸實(shí)現(xiàn)起來還是相當(dāng)快的了。
用偽代碼描述:
這個(gè)算法的出口就是你要生成多少終局。
七、單元測(cè)試與代碼覆蓋率分析
總共設(shè)計(jì)了13個(gè)測(cè)試,覆蓋率為88.33%,接近90%,已達(dá)個(gè)人預(yù)期的80%。
單元測(cè)試主要針對(duì)輸入的判斷作了較多的測(cè)試,因?yàn)槌绦蚴紫纫芊治雒钚兄噶畹恼_性,設(shè)計(jì)了2組正確輸入也設(shè)計(jì)了3組錯(cuò)誤輸入,對(duì)參數(shù)分析作了比較完備的測(cè)試,對(duì)類的構(gòu)造函數(shù)也進(jìn)行了測(cè)試以判斷初始化情況,對(duì)儲(chǔ)存數(shù)組、生成數(shù)獨(dú)、求解數(shù)獨(dú)、輸出數(shù)獨(dú)等核心模塊也都分別設(shè)計(jì)了測(cè)試。具體內(nèi)容可以參見測(cè)試代碼,不過需要注意單元測(cè)試時(shí)要將sudoku.h文件中Sudoku類的private注釋掉,因?yàn)槲业念悢?shù)據(jù)成員原本全私有,且不少方法封裝的可能有點(diǎn)緊湊不好切入斷言,故為了單元測(cè)試方便,需要改成公有。注意、注意、注意使用我的單元測(cè)試時(shí)一定要將私有改公有!!!
八、項(xiàng)目總結(jié)
本次個(gè)人項(xiàng)目歷經(jīng)十余天,遇到了許多奇奇怪怪的bug,感覺不再是對(duì)代碼能力的考驗(yàn)了而是對(duì)意志力的磨練。
8.1 個(gè)人的提升
面向?qū)ο笏枷?/strong>
第一次正式使用VS構(gòu)建C++工程,使用多文件進(jìn)行對(duì)項(xiàng)目分模塊化,而不再像之前是單文件模式,模塊化構(gòu)建使自己的思路與邏輯更加清晰,并且配合C++類的封裝等面向?qū)ο蟮木幊趟枷胧沟么a結(jié)構(gòu)也更加清晰。這也讓我感受到了面向?qū)ο缶幊痰膬?yōu)秀之處,我們的世界本身就是物物的作用關(guān)系,而對(duì)象則是物物的代碼抽象化,而作用關(guān)系則是方法,我們的世界中有顯性的作用關(guān)系,也有隱性的,而宏觀物的內(nèi)部也有更加具體的微觀物,這就是公有與私有、類與成員的關(guān)系。
工程能力
什么是工程?個(gè)人認(rèn)為工程是綜合、是規(guī)范。綜合說明了實(shí)施的過程必然是繁瑣的,有一定量的,需要的知識(shí)也是多方面的,軟件工程亦是如此,在本項(xiàng)目中,要學(xué)習(xí)C++的一些特性,還要熟悉VS的一些使用技巧,尤其是編寫代碼時(shí)要思考該怎么使用算法?要思考應(yīng)該如何具體實(shí)現(xiàn)。規(guī)范則說明了代碼不是隨便編寫的,例如首要的就是代碼風(fēng)格規(guī)范,有一個(gè)良好的風(fēng)格規(guī)范一方面是便于閱讀,另一方面則是使代碼邏輯更加嚴(yán)謹(jǐn),減少了不必要的錯(cuò)誤。規(guī)范還體現(xiàn)在單元測(cè)試,之前的程序練習(xí)要求能跑就好,沒有多少真正的測(cè)試,而軟件開發(fā)的單元測(cè)試也對(duì)應(yīng)了一般意義上的工程開發(fā),像建樓房,有各種驗(yàn)收審查,各個(gè)部分的檢驗(yàn),而這就是代碼的各個(gè)模塊,單元測(cè)試是軟件的一質(zhì)量測(cè)試,雖實(shí)現(xiàn)不同但意義是一樣的。
模仿與學(xué)習(xí)
在本項(xiàng)目中,很多東西都是自己以前沒有遇到過的,沒有任何經(jīng)驗(yàn),只能模仿別人的方法,并通過模仿來學(xué)習(xí)自己未知的知識(shí)與經(jīng)驗(yàn)。在這里,非常感謝一位北航學(xué)長(zhǎng),他的項(xiàng)目給我很多啟發(fā)與靈感,在模仿他的一些方法的過程中學(xué)習(xí)到了很多,減少了很多彎路。模仿是學(xué)習(xí)的一種基礎(chǔ),先模仿獲得初步的經(jīng)驗(yàn),有了經(jīng)驗(yàn)我們才能更好的反思與改進(jìn),沒有天生就會(huì)的,而有了足夠的經(jīng)驗(yàn)我們才能夠創(chuàng)新與創(chuàng)造。
這次的個(gè)人項(xiàng)目對(duì)模仿與學(xué)習(xí)能力有極大的考驗(yàn),在此之前都沒有過比較深入的看官方文檔的經(jīng)歷,學(xué)會(huì)如何看文檔、技術(shù)博客,從中獲取自己所需要的知識(shí)與經(jīng)驗(yàn)是一種屬于成長(zhǎng)式的能力,這種能力將會(huì)伴隨我們終身并成為我們終身學(xué)習(xí)的關(guān)鍵一環(huán)。
8.2 不足
個(gè)人
英文水平有待提高,在看文檔的時(shí)候習(xí)慣性將網(wǎng)址的en-us改成zh-cn,要是沒有就會(huì)啟動(dòng)網(wǎng)頁翻譯,博客也是中文博客,沒有養(yǎng)成在Stack Overflow上尋找解析的習(xí)慣。對(duì)待問題總是沒有徹徹底底解決的感覺,不過這個(gè)涉及的能力實(shí)在不知道該怎么說了。注意力目前還是放在了工具的使用上了,作為一名軟件開發(fā)人員,我們不光要會(huì)使用輪子,更要明白輪子的構(gòu)建,以及軟件開發(fā)方法。
項(xiàng)目本身
例如程序本身的穩(wěn)定性方面沒有做過較多的研究,像程序生成100萬數(shù)獨(dú)終局的時(shí)間就有一定的波動(dòng),沒有將其壓到一個(gè)較低的穩(wěn)定值,也沒有做多平臺(tái)測(cè)試,只是在個(gè)人的Win10 x64上進(jìn)行了測(cè)試。也沒有去完成項(xiàng)目的附加題——界面程序,這個(gè)是感覺很耽誤時(shí)間,這段時(shí)間要有許多科目的學(xué)習(xí),不能將時(shí)間全砸在軟工的項(xiàng)目上,如果是小學(xué)期課程就會(huì)好很多,沒有其他課程的干擾,可以一心一意的撲在項(xiàng)目上。
課程設(shè)計(jì)
這個(gè)個(gè)人項(xiàng)目應(yīng)該有討論群的,應(yīng)該有多位助教幫忙答疑解惑。畢竟我們這是本科二年級(jí)的課程,縱然我們有一定的自學(xué)能力,但是有人指導(dǎo)和沒人的捉瞎的感覺是不一樣的。老師在課上也應(yīng)該及時(shí)評(píng)閱同學(xué)的個(gè)人項(xiàng)目,例如中期點(diǎn)評(píng)啥的,這樣可以避免很多不必要的錯(cuò)誤,或者舉一些實(shí)際的例子給我們演示一下,而不是照著課本講一些目前對(duì)我們來說的很宏觀的方法,工廠都有師傅帶徒弟進(jìn)行實(shí)操練習(xí),這個(gè)課也應(yīng)如此,講結(jié)構(gòu)設(shè)計(jì)就應(yīng)該給個(gè)完整的實(shí)際例子,而不是像書上那樣的言簡(jiǎn)意賅,非常抽象,講白盒測(cè)試、黑盒測(cè)試就應(yīng)該給個(gè)具體例子、具體測(cè)試工具演示一下到底是怎么弄的,只講宏觀的東西是很難弄明白的。
致謝
[buaa-SE-2017]個(gè)人項(xiàng)目
感謝北航辛學(xué)長(zhǎng)的項(xiàng)目給了我很多靈感與經(jīng)驗(yàn),讓我少走了許多不必要的彎路。通過學(xué)長(zhǎng)的代碼學(xué)習(xí)到了C++面向?qū)ο缶幊痰幕痉椒?#xff0c;同時(shí)其簡(jiǎn)潔優(yōu)美的代碼風(fēng)格與技巧讓人留戀與難忘!
Visual Studio 文檔
感謝微軟的官方文檔,讓我在面對(duì)各種奇奇怪怪的錯(cuò)誤與警告提示時(shí)有了一些基本概念與策略,同時(shí)通過文檔也初步學(xué)習(xí)與掌握了單元測(cè)試方法等。其言簡(jiǎn)意賅的描述讓人刻骨銘心!
【算法研究】數(shù)獨(dú)高效完全解生成算法的研究和實(shí)現(xiàn)、帶你玩轉(zhuǎn)Visual Studio——性能分析與優(yōu)化、Git 中忽略某些文件或者文件夾······
這里無法一一列舉參考過的博客,感謝大佬們的經(jīng)驗(yàn)分享,讓我在痛苦與絕望時(shí)看見了希望的光火!其開源分享的精神讓人感動(dòng)!
感謝老師與同學(xué),這次的個(gè)人項(xiàng)目對(duì)個(gè)人確實(shí)有所歷練,大概能夠理解老師的用意!
總結(jié)
以上是生活随笔為你收集整理的软件工程基础课-个人项目-数独的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue3+Typescript---Co
- 下一篇: 第二次迭代总结