軟體工程基礎 個人專案 數獨

2022-07-27 10:30:17 字數 3389 閱讀 6503

任務:實現乙個能夠生成數獨局並且能求解數獨問題的控制台程式。

1、github:

2、時間耗費

psd2.1

personnal software process stages

預估耗時(分鐘)

實際耗時(分鐘)

planning

計畫40

40.estimate

.估計這個任務需要多長時間

development

開發150

120.analysis

.需求分析(包括學習新技術)

180200

.design spec

.生成設計文件

150150

.design review

.設計複審(和同事審核設計文件)

6060

.coding standard

.**規範(為目前的開發制定合適的規範)

6060

.design

具體設計

8080

.coding

.具體編碼

1600

1800

.code review

.**複審

100150

.test

.測試(自我測試,修改**,提交修改)

200250

reporting

報告120

150.test report

.測試報告

80100

.size measurement

.計算工作量

4030

.postmortem & process improvement plan

.事後總結,並提出過程改進計畫

5040

合計2910

3190

3、解題思路:

此專案可以細分為兩個功能:生成數獨、解數獨。

生成數獨我考慮採用的是回溯的方法,對殘缺數獨不斷求解,從而得到相應數量的完善的數獨。

確定好方法之後便是漫長的學習之路,參考了相應的回溯演算法的部落格以及其他演算法的數獨生成部落格。

在學習過程中也見識到了很多新的思路生成數獨,比如說對乙個已經合理的數獨進行變換,然後判斷其在變換之後是否依然是符合數獨規範。通過這種方式生成數獨,首先會保證結果的互異性,其次相比於回溯不需要大量的計算,節省了大量的時間。

但是由於已經開始用回溯演算法寫了,所以之後的改高階段會再嘗試一下敢變思路。

4、設計實現過程

程式主體是3個函式

judge():解數獨函式中用此函式判斷回溯條件。

solve():具體的解函式本體。

construct():構建函式。

封裝成函式有利於**的復用,與此同時提公升了程式的簡潔性和可讀性。

函式邏輯說明:

生成數獨函式construct():首先進入函式判斷目前生成的數獨是否數量達標,若符合標準則結束函式體,否則進入下一步。下一步判斷一下1-9個數字是否經過遍歷數字全排列完,若是則跳到行間的全排列判斷,若行全排完就結束函式體,否則改變行的排列順序再初始化數排列進行終局輸出。若判斷數字全排未完,就改變量字的順序再進行終局生成。也就是兩個巢狀的判斷,數字全排和行陣列的全排。

解數獨函式solve():解數獨首先加乙個判斷條件,看是否已經生成了需求規定的9x9數獨,若是輸出數獨並結束;否則進行遞迴:利用judge函式判斷防止條件,能放就放並進入下一層遞迴,不能就回溯到上一層遍歷到下乙個數再進行遞迴,最終遞迴結束返回最初的判斷,進行數獨輸出。

其實思路很簡單但是實際執行的話,若給定的數獨數量是1000000或更大跑的時間差不多是在20s,所以還是有待提公升的。

5、效能改進及思路

測試程式的時候,同學建議我優化一下數字的輸出,construct函式其實是最耗時的,所以優化也是從這裡著手。

之前使用的printf輸出格式,但其實putchar()這種以字元形式輸出會更節省時間,所以我替換了之前的printf輸出方式,結果生成時間減少到了7s左右,相較之前的20多秒提公升了很多。

效能測試:

這是輸入為1000000時的效能情況

6、**說明(思路解釋+注釋說明)

旁邊的小銘同學提供給我一種非常好的思路:就是對任意的乙個終局數獨,任意交換1-3、4-6、7-9行的順序得到的依然是滿足需求的數獨,這也就彌補了8!=40320遠遠小於1000000這樣的大數字的尷尬境地。

下面是具體的construct()函式**

void construct(intn);

inttemp_column;

char fn[10] = ;

if (count

printf("\n

");}

count++;

t++;

if (count ==n)

break

;

else

printf("\n

");}

while (t<40320

);

if (count ==n)

break

; }}}

}

點選+號檢視**

下面是具體的solve()函式**

void solve()//

解數獨;

for (int i = 1; i <= 9; i++)

;for (int j = 1; j <= 9; j++)

else}}

if(flag)

}if (!flag)

if (i < 9

) putchar('\n

');}}}

點選+號檢視**

解數獨就是要有乙個判斷函式judge()用來在遍歷的階段看是否能夠發放置這個數,思路就是回溯法~

7、實際耗時

具體的時間消耗見最上方的**。

軟體工程個人專案 數獨

專案位址 github倉庫 psp 2.1 personal software process stages 預計耗時 分鐘 實際耗時 分鐘 planning 計畫50 60estimate 估計這個任務需要多久 300360 development 開發240 270analysis 需求分析 2...

軟體工程基礎 個人專案 數獨(2)

第乙個數字為 9 6 9 1 7 其餘八個數字為1 6,8,9的隨機排序,共8!種 1 從網上查閱資料得知,如果從第二行開始,每行為第一行左移3 6 1 4 7 2 5 8的結果,則生成的結果為合格的數獨終局 2 隨意交換數獨的1 2 3行,4 5 6行,7 8 9行,或者交換1 2 3列,4 5 ...

軟體工程基礎 個人專案 數獨(5)

1.生成終局時,加入2,3 4,5,6 7,8,9行交換的情況以增加不重複的終局數量 原情況下,第2 9行為第一行左移固定數量得到,移動量由陣列move陣列儲存,行交換的實現只需交換對應的移動量。將move陣列設為二維陣列,每一行對應乙個移動量的情況,共72行。將原 中move的使用方式 num i...