日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

软件工程基础课-个人项目-数独

發(fā)布時(shí)間:2024/3/13 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 软件工程基础课-个人项目-数独 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  • 一、項(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

PSP2.1Personal Software Process Stages預(yù)估耗時(shí)(分鐘)實(shí)際耗時(shí)(分鐘)
Planning計(jì)劃
·Estimate·估計(jì)這個(gè)任務(wù)需要多長(zhǎng)時(shí)間1020
Development開發(fā)
·Analysis·需求分析(包括學(xué)習(xí)新技術(shù))60120
·Design Spec·生成設(shè)計(jì)文檔300120
·Design Review·設(shè)計(jì)復(fù)審(和同事審核設(shè)計(jì)文檔)//
·Coding Standard·代碼規(guī)范(為目前的開發(fā)制定合適的規(guī)范)120180
·Design·具體設(shè)計(jì)120180
·Coding·具體編碼10801200
·Code Review·代碼復(fù)審30060
·Test·測(cè)試(自我測(cè)試,修改代碼,提交修改)300960
Reporting報(bào)告
·Test Report·測(cè)試報(bào)告6060
·Size Measurement·計(jì)算工作量3030
·Postmortem & Process Improvement Plan·事后總結(jié),并提出過程改進(jìn)計(jì)劃180120
<script id="MathJax-Element-8" type="math/tex"> </script>合計(jì)25603050

三、解題思路

看老師的要求文檔,數(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)快的了。
用偽代碼描述:

function Backtracking_Search(i, j) //i,j表示的是大九宮格里的(i, j)格 {if 已生成的終局?jǐn)?shù) >= 要求生成的終局?jǐn)?shù):return;if 生成一個(gè)新終局: //檢查生成新終局的便捷辦法就是判斷邊界條件{ //當(dāng)格子的位置移出9×9的大九宮格外說明就有新終局了已生成的終局?jǐn)?shù)++;輸出新生成的終局; //或者先存起來一起輸出return;}if 到了一行的最末: //這個(gè)看你是怎么搜索了,我是按行的,也可以按列{換行到下一行開頭; //我的就是i++;j=1;換列就是i=1;j++;}for num from 1 to 9:{if 已生成的終局?jǐn)?shù) >= 要求生成的終局?jǐn)?shù):return;if 準(zhǔn)備填入(i,j)格的數(shù)num滿足數(shù)獨(dú)規(guī)則:{將num賦值給(i,j)格;Backtracking_Search(i, j); //滿足條件就繼續(xù)遞歸下去}}(i, j)格重置為0; //說明填什么數(shù)字都不滿足數(shù)獨(dú)規(guī)則,要開始回溯,這個(gè)位置要重置為0 }

這個(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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。