201971010237-尚潔 實驗三 結對專案—《{0-1}KP 例項資料集演算法實驗平臺》專案報告
專案 | 內容 |
---|---|
課程班級部落格連結 | 2019級卓越工程師班 |
這個作業要求連結 | 實驗三 軟體工程結對專案 |
我的課程學習目標 | (1)體驗軟體專案開發中的兩人合作,練習結對程式設計 (2)掌握Github協作開發程式的操作方法。 (3)使用Java編寫D{0-1}KP 例項資料集演算法實驗平臺 |
這個作業在哪些方面幫助我實現學習目標 | (1)自學《構建之法》第3-4章內容,學習本次作業相關概念。 (2)結對程式設計,評價對方《實驗二 軟體工程個人專案》並學習對方優點。 (3)合作開發設計D{0-1}KP 例項資料集演算法實驗平臺。 (4)查閱資料設計遺傳演算法解決D{0-1}KP。 |
結對方學號-姓名 | 201971010216-李斌 |
結對方本次部落格作業連結 | |
本專案Github的倉庫連結地址 | https://github.com/sj319134578/SJ |
正文:
任務1:閱讀《現代軟體工程—構建之法》第3-4章內容,理解並掌握程式碼風格規範、程式碼設計規範、程式碼複審、結對程式設計概念
-
程式碼風格規範:簡明,易讀,無二義性。
- 縮排:4個空格
- 行寬:100字元
- 括號:複雜的條件表示式中,用括號清楚表示優先順序
- 分行:不把多條語句放在一行上,不把多個變數定義在一行上
- 命名:儘量簡潔規範
- 下劃線:下劃線用來分隔變數名字中的作用域標註和變數的語義,如:一個型別的成員變數通常用m.來表示,或者簡單地用一個下劃線“_”來做字首。移山公司規定下劃線一般不用在其他方面。
- 大小寫:所有的型別/類/函式名都用Pascal 形式,所有的變數都用Camel形式類/型別/變數:名詞或組合名詞,如 Member、ProductInfo 等。函式則用動詞或動賓組合詞來表示,如 get/set、RenderPage( )。
-
註釋:適當註釋
-
程式碼設計規範:函式,goto,錯誤處理以及如何處理C++中的類。
-
程式碼複審:看程式碼是否在“程式碼規範”的框架內正確地解決了問題。主要有自我複審,團隊複審以及同伴複審三種方式。
-
結對程式設計:兩人結對程式設計,一對程式設計師肩並肩,平等地,互補地進行開發工作。
任務2:兩兩自由結對,對結對方《實驗二 軟體工程個人專案》的專案成果進行評價
專案 | 內容 |
---|---|
結對方部落格連結 | 201971010216-李斌-實驗二 軟體工程 個人專案 - 用所學知識解決0/1揹包問題 |
結對方Github專案倉庫連結 | 倉庫 |
- 對結對方的部落格評論:
- 博文結構:
整體結構比較簡潔,但是排版太亂,後面可以注意一下。 - 博文內容:
完成了大部分實驗要求的內容,功能設計模組使用圖片示意,較為清晰,詳細講解了各個演算法的實現。 - 博文結構與PSP中“任務內容”列的關係:
博文結構與“內容任務”列並非完全對應 - PSP中“計劃共完成需要的時間”與“實際完成需要的時間”兩列資料的差異化分析與原因探究:
博主提到程式碼整合到一起回溯有巨大的問題,散點圖的相關C++程式碼也有問題,無法顯示,且對github平臺的使用不夠熟悉,導致實際完成時間與計劃共需要的時間不一致。
- 博文結構:
- 克隆專案,閱讀並測試
克隆專案至本地資料夾:
將專案匯入Codeblocks進行測試
觀察到結對方沒有完成全部所要求的功能,並未完成資料讀取、演算法求解部分,和繪製散點圖等功能。
- 程式碼核查表:
專案 | 內容 |
---|---|
概要部分 | |
程式碼符合需求和規格說明麼? | 否,並未完成全部功能 |
程式碼設計是否考慮周全? | 否 |
程式碼可讀性如何? | 較好 |
程式碼容易維護麼? | 易維護 |
程式碼的每一行都執行並檢查過了嗎? | 是 |
設計規範部分 | |
設計是否遵從已知的設計模式或專案中常用的模式? | 是 |
有沒有硬編碼或字串/數字等存在? | 有 |
程式碼有沒有依賴於某一平臺,是否會影響將來的移植? | 對移植影響較小 |
開發者新寫的程式碼是否用已有的Library/SDK/Framework中的功能實現? | 是 |
在本專案中是否存在類似的功能可以通過呼叫而不用全部重新實現? | 是 |
有沒有無用的程式碼可以清除? | 有 |
程式碼規範部分 | |
修改的部分符合程式碼標準和風格麼? | 符合 |
具體程式碼部分 | |
有沒有對錯誤進行處理?對於呼叫的外部函式,是否檢查了返回值或處理了異常? | 已處理 |
引數傳遞有無錯誤,字串的長度是位元組的長度還是字元的長度,是從0開始計數還是從1開始計數 | 無錯誤;字元的長度;從0開始 |
邊界條件是如何處理的?switch語句和default分支是如何處理的?迴圈有沒有可能出現死迴圈? | 前提分析推導邊界條件;無switch語句和default分支;有 |
有沒有使用斷言來保證我們認為不變的條件真的得到滿足? | 沒有 |
對資源的利用,是在哪裡申請,在哪裡釋放的?有無可能存在資源洩露?有沒有優化的空間? | 有;不存在;有 |
資料結構中有沒有用不到的元素? | 有 |
效能 | |
程式碼的效能如何?最壞的情況是怎麼樣的? | 效能一般 |
程式碼中,特別是迴圈中是否有明顯可優化的部分? | 有 |
對於系統和網路的呼叫是否會超時?如何處理? | 否 |
可讀性 | |
程式碼可讀性如何?有沒有足夠的註釋? | 沒有足夠的註釋,但程式碼較為清晰,可讀性較好 |
可測試性 | |
程式碼是否需要更新或建立新的單元測試? | 是 |
- 結對方專案倉庫中的日誌資料
Commits資料:如圖所示,幫助結對方完成了揹包資料讀取與選擇的功能,並上傳至Github。
- Forks資料:如圖所示,對結對方的專案進行了Fork操作
- 將修改提交到指定一方的倉庫中
任務3:採用兩人結對程式設計方式,設計開發一款{0-1}KP 例項資料集演算法實驗平臺,使之具有以下功能:
-
需求分析
從若干具有價值係數與重量係數的物品(或項)中,選擇若干個裝入一個具有載重限制的揹包,並使裝入物品的重量係數之和在不超過揹包載重前提下價值係數之和達到最大。
-
功能分析
1、可讀取實驗資料,有效呈現所有資料;
2、用讀取的資料繪製出以重量為橫軸、價值為縱軸的資料散點圖;
3、將資料按項集第三項的價值:重量比進行非遞增排序;
4、使用者能夠自主選擇動態規劃演算法、回溯演算法求解資料的最優解和求解時間;
5、資料的最優解、求解時間和解向量可儲存為txt檔案 -
軟體設計
1、D{0-1}KP 例項資料集需儲存在資料庫;
2、平臺可動態嵌入任何一個有效的D{0-1}KP 例項求解演算法,並儲存演算法實驗日誌資料;
3、人機互動介面要求為GUI介面;
4、查閱資料,設計遺傳演算法求解D{0-1}KP,並利用此演算法測試要求(3); -
軟體實現及核心功能程式碼展示
連線資料庫相關程式碼
//函式6:建立資料庫連線
public static Connection getConnection() {
Statement stmt;
ResultSet rs;
Connection con = null;
PreparedStatement ps = null ;
try {
out.println("begin connection...");
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;DatabaseName=bag","sj","root");
// 建立Statement物件
stmt = con.createStatement();
/**
* Statement createStatement() 建立一個 Statement 物件來將 SQL 語句傳送到資料庫。
*/
//每次執行插入語句前先刪除之前存入的資料
String sql="delete from data ";
//執行SQL刪除語句
stmt.executeUpdate(sql);
out.println("已刪除之前的資料!\n\n");
//將揹包資料插入資料庫
out.println("開始插入揹包資料...");
int t=0;
for(int i=0; i<n; i++)
{
sql = "insert into data(weight,value) values (?,?)";
ps = con.prepareStatement(sql);
ps.setInt(1, w[i]);
ps.setInt(2, v[i]);
// 執行資料庫插入語句
ps.executeUpdate() ;
//stmt.executeUpdate(sql);
t++;
}
out.println("成功插入"+t+"條記錄!");
//查詢資料庫中插入的記錄
out.println("查詢記錄如下:");
sql = "select * from data" ;
/**
* ResultSet executeQuery(String sql) throws SQLException 執行給定的 SQL
* 語句,該語句返回單個 ResultSet 物件
*/
rs = stmt.executeQuery(sql) ;
int w1,v1;
while(rs.next())
{
w1 = rs.getInt(1);
v1 = rs.getInt(2);
out.println("重量" + w1 +" 價值" + v1);
}
out.println("end.");
}
catch (Exception e) {
out.println(e);
}
return con;
}
資料庫儲存部分實現:
後臺顯示記錄:
儲存日誌相關關鍵部分程式碼
try{
PrintStream mytxt=new PrintStream("./log.txt");
//儲存輸出日誌資訊
PrintStream out=System.out;
System.setOut(mytxt);
System.out.println("文件執行的日期是:"+new Date());
// 記錄輸入輸出的記錄
System.setOut(out);
mytxt.close();
System.out.println("日期儲存完畢(演算法結果已儲存至log檔案)");
}catch(FileNotFoundException e){
e.printStackTrace();
}
儲存日誌檔案如下:
- 查閱資料,設計遺傳演算法求解D{0-1}KP,並利用此演算法測試要求(3)
- 遺傳演算法
遺傳演算法(Genetic>遺傳演算法(Genetic Algorithm,GA)是進化計算的一部分,是模擬達爾文的遺傳選擇和自然淘汰的生物進化過程的計算模型,是一種通過模擬自然進化過程搜尋最優解的方法。該演算法簡單、通用,魯棒性強,適於並行處理。
- 遺傳演算法的基本步驟是:
(1)初始化:設定進化代數計數器t=0,設定最大進化代數T,隨機生成M個個體作為初始群體P(0)。
(2)個體評價:計算群體P(t)中各個個體的適應度。
(3)選擇運算:將選擇運算元作用於群體。選擇的目的是把優化的個體直接遺傳到下一代或通過配對交叉產生新的個體再遺傳到下一代。選擇操作是建立在群體中個體的適應度評估基礎上的。
(4)交叉運算:將交叉運算元作用於群體。遺傳演算法中起核心作用的就是交叉運算元。
(5)變異運算:將變異運算元作用於群體。即是對群體中的個體串的某些基因座上的基因值作變動。群體P(t)經過選擇、交叉、變異運算之後得到下一代群體P(t+1)。
(6)終止條件判斷:若t=T,則以進化過程中所得到的具有最大適應度個體作為最優解輸出,終止計算。
參考文獻:
[1]吳聰聰,賀毅朝,趙建立.求解折扣{0-1}揹包問題的新遺傳演算法[J].計算機工程與應用,2020,56(07):57-66.
[2]楊洋,潘大志,劉益,譚代倫.折扣{0-1}揹包問題的簡化新模型及遺傳演算法求解[J].計算機應用,2019,39(03):656-662.
遺傳演算法虛擬碼,如下圖所示。
-
提供兩人在討論、細化和程式設計時的結對照片。
-
提供此次結對作業的PSP
任務內容 | 計劃共完成需要的時間/分鐘 | 實際完成需要的時間/分鐘 |
---|---|---|
閱讀《現代軟體工程—構建之法》第3-4章 | 50 | 55 |
對專案博文作業進行閱讀並進行評論 | 20 | 20 |
克隆結對方專案原始碼到本地機器,閱讀並測試執行程式碼 | 100 | 120 |
依據複審結果用github的Fork、Clone、Push等操作對同伴個人專案倉庫的原始碼進行合作修改 | 90 | 90 |
D{0-1}KP 例項資料集儲存在資料庫 | 40 | 60 |
將資料庫資料讀取出來 | 40 | 70 |
用讀出來的資料繪製散點圖並顯示在人機互動頁面 | 60 | 270 |
動態規劃演算法結果顯示在前端 | 60 | 120 |
回溯演算法結果顯示 | 40 | 75 |
將資料項顯示在前端,按其第三項進行排序並顯示 | 80 | 100 |
平臺可動態嵌入任何一個有效的D{0-1}KP 例項求解演算法,並儲存演算法實驗日誌資料 | 100 | 120 |
人機互動介面要求為GUI介面 | 40 | 50 |
查閱資料,設計遺傳演算法求解D{0-1}KP,並利用此演算法測試要求 | 200 | 450 |
- 小結感受
兩人合作真的能夠帶來1+1>2的效果嗎?通過這次結對合作,請談談你的感受和體會。
這次的實驗我們嘗試了結對程式設計,通過結對程式設計我們可以一起去交流學習。結對程式設計的效果是真的挺大的,通過結對程式設計我們共同合作,能夠想到一些對方沒有考慮地方,可以分享知識、共同解決遇到的問題。兩個人合作完成一個專案,要比起自己單獨去完成效果好很多,不僅會減輕雙方的工作量,還可以在合作中最大化發揮自己的優點,同時也可以從對方身上學到很多自己不擅長的技術,互相彌補,共同進步。而且通過這次的結對程式設計,我們學會了合作學習、交流,知道怎麼團隊工作。
把每個人的工作有序地組織起來,就是團隊的流程。這裡說的“有序”,並不是“無爭論”。不同意見的衝突在所難免,一個好的團隊流程能把衝突的積極方面(各自盡力把自己的工作做好,說服別人)釋放出來,而避免消極方面(因為衝突而產生的消極、牴觸情緒等)。