201971010242-王凱英 實驗三 結對專案—《{0-1}KP 例項資料集演算法實驗平臺》專案報告
專案 | 內容 |
---|---|
課程班級部落格連結 | 班級 |
這個作業要求連結 | 作業 |
我的課程學習目標 | (1)體驗軟體專案開發中的兩人合作,練習結對程式設計(Pair programming)。(2)掌握Github協作開發軟體的操作方法。 |
這個作業在哪些方面幫助我實現學習目標 | (1)通過本次實驗,首次開展軟體工程結對專案,熟悉了專案製作的基本流程。(2)再次練習使用GitHub釋出軟體專案 |
結對方學號-姓名 | 201971010242-王亞亞 |
結對方本次部落格作業連結 | 連結 |
本專案Github的倉庫連結地址 | 倉庫 |
- 任務1:閱讀《現代軟體工程—構建之法》第3-4章內容,理解並掌握程式碼風格規範、程式碼設計規範、程式碼複審、結對程式設計概念;
程式碼風格規範、程式碼設計規範、程式碼複審、結對程式設計概念; 程式碼規範: 程式碼設計規範,牽涉到程式設計、模組之間的關係、設計模式等方方面面的通用原則。程式碼設計規範: 程式碼設計規範不光是程式書寫的格式問題,而且牽涉到程式設計、模組之間的關係、設計模式 等方方面面,這裡又有不少內容與具體程式設計語言息息相關(如C、C++. Java、C#),但 是也有通用的原則,這裡主要討論通用的原則。
程式碼複審目的:
找出程式碼的錯誤
(1) 編碼錯誤,比如一些碰巧騙過了編譯器的錯誤;
(2) 不符合團隊程式碼規範的地方。
結對程式設計:
在結對程式設計模式下,一對程式設計師肩並肩地、平等地、互補地進行開發工作。兩個程式設計師並排坐在一臺電腦前,面對同一個顯示器,使用同一個鍵盤,同一個滑鼠一起工作。他們一起分析,一起設計,一起寫測試用例,一起編碼,一起單元測試,一起整合測試,一起寫文件等。
-
任務2
概要部分: -
程式碼符合需求和規格說明麼?
答:程式碼符合需求和規格說明。
- 程式碼設計是否考慮周全
答:程式碼設計考慮周全。
- 程式碼可讀性如何?
答:程式碼可讀性較好
- 程式碼容易維護麼?
答:程式碼容易維護。
- 程式碼的每一行都執行並檢查過了嗎?
答:程式碼的每一行都執行並檢查過了。
設計規範部分:
- 設計是否遵從已知的設計模式或專案中常用的模式?
答:設計遵從已知的設計模式或專案中常用的模式。
- 有沒有硬編碼或字串/數字等存在?
答:存在硬編碼
- 程式碼有沒有依賴於某一平臺,是否會影響將來的移植(如Win32到Win64)?
答:程式碼實在win64上進行的編碼,不太清楚在win32上能否執行,未進行測試。
- 有沒有無用的程式碼可以清除?
答:基本上沒有需要清除的程式碼。
程式碼規範部分:
答:修改的部分符合程式碼標準和風格。
具體程式碼部分:
- 有沒有對錯誤進行處理?對於呼叫的外部函式,是否檢查了返回值或處理了 異常?
答:對錯誤進行了處理,對於呼叫的外部函式,檢查了返回值或處理了異常。
- 資料結構中有沒有用不到的元素?
答:資料結構中沒有用不到的元素。
效能:
- 程式碼中,特別是迴圈中是否有明顯可優化的部分?
答:程式碼中,特別是迴圈中沒有明顯可優化的部分。
- 可讀性:
答:程式碼沒有足夠的註釋,註釋很少,程式碼可讀性不是很好。
- 可測試性:
答:程式碼是不需要更新或建立新的單元測試。
第五步:結對方專案倉庫中的Fork、Clone、Push、Pull request、Merge pull request日誌資料:
- Fork:
將結對方的專案複製過來,相當於一個分支;專案複製到自己的github中,於是本地就有了和結對方相同命名的倉庫。
- Clone:
從自己的github上把fork過來的複製到本地,這樣本地就有了結對方的專案。
- Push:
在本地專案進行修改開發後,最後同步到我的github上的倉庫中。
- Pull request:
把自己github中的已經修改的內容申請同步到最初那個開發者的專案中並作出比較。由於在push階段對結對方的程式碼未作出修改(個人覺得結對方程式碼無需修改),所以比較結果是兩個專案並無差異。
- 任務三
採用兩人結對程式設計方式,設計開發一款D{0-1}KP 例項資料集演算法實驗平臺,使之具有以下功能:
(1)平臺基礎功能:實驗二 任務3;
(2)D{0-1}KP 例項資料集需儲存在資料庫;
(3)平臺可動態嵌入任何一個有效的D{0-1}KP 例項求解演算法,並儲存演算法實驗日誌資料;
(4)人機互動介面要求為GUI介面(WEB頁面、APP頁面都可);
(5)查閱資料,設計遺傳演算法求解D{0-1}KP,並利用此演算法測試要求(3);
(6)附加功能:除(1)-(5)外的任意有效平臺功能實現。
一、需求分析
-
折扣0/1揹包問題,動態規劃演算法,回溯演算法;
-
從定的檔案中讀取出正確的資料並儲存;
-
讀取資料並對資料進行處理,需要用到資料的切片技術;
-
繪製資料散點圖要用到資料的視覺化技術;
-
將求解出的資料儲存或匯出檔案
-
D{0-1}KP 例項資料集需儲存在資料庫;
-
平臺可動態嵌入任何一個有效的D{0-1}KP 例項求解演算法,並儲存演算法實驗日誌資料;
-
人機互動介面要求為GUI介面。
二、功能設計
- 繪製任意一組D{0-1}KP資料以重量為橫軸、價值為縱軸的資料散點圖;
- 對任意一組D{0-1}KP資料按項集第三項的價值:重量比進行非遞增排序;
- 使用者能夠自主選擇動態規劃演算法、回溯演算法求解指定D{0-1} KP資料的最優解和求解時間(以秒為單位);
- 任意一組D{0-1} KP資料的最優解、求解時間和解向量
三、設計實現
在實驗過程中,此次實驗要求的技術與我在此之前的掌握的技術有一定差距。所以我複習了大學三年級第一學期在《演算法設計與分析》課程中學習到的動態規劃演算法與回溯演算法求解0/1揹包問題的內容,循序漸進,推進實驗的程序。
1、動態規劃演算法
動態規劃演算法的核心思想是:
將大問題劃分為小問題進行解決,從而一步一步獲得最優解的處理演算法。
動態規劃演算法與分治演算法類似,其基本思想也是將代求問題分解成若干子問題,先求解子問題,然後從這些子問題的解得到原問題的解。
與分治演算法不同的是,適合於動態規劃求解的問題,經分解得到的子問題往往不是互相獨立的,即下一個子階段的求解過程是建立在上一個子階段的解的基礎上,進行進一步的求解。
2、回溯演算法
-
顧名思義,回溯法一個很顯著的特徵就是回溯,即在處理完某種情況或出現不能繼續進行的情況時,要退回到之前的某個“交叉口”,處理另一種可能。
-
回溯法是一種非常有效的方法,有“通用的解題法”之稱。它有點像窮舉法,但是更帶有跳躍性和系統性,他可以系統性的搜尋一個問題的所有的解和任一解。回溯法採用的是深度優先策略。通常,回溯法會定義一個解空間,這個解空間通常是以圖或樹的形式呈現出來的。揹包問題的解空間是樹的形式,屬於深度優先搜尋。
-
回溯法在確定瞭解空間的結構後,從根結點出發,以深度優先的方式搜尋整個解空間,此時根結點成為一個活結點,並且成為當前的擴充套件結點。每次都從擴充套件結點向縱向搜尋新的結點,當演算法搜尋到瞭解空間的任一結點,先判斷該結點是否肯定不包含問題的解(是否還能或者還有必要繼續往下搜尋),如果確定不包含問題的解,就逐層回溯;否則,進入子樹,繼續按照深度優先的策略進行搜尋。當回溯到根結點時,說明搜尋結束了,此時已經得到了一系列的解,根據需要選擇其中的一個或者多個解即可。
回溯法解決問題一般分為三個步驟:
(1)針對所給問題,定義問題的解空間;
(2)確定易於搜尋的解空間結構;
(3)以深度優先的方式搜尋解空間。
3、遺傳演算法
- 查閱資料,設計遺傳演算法求解D{0-1}KP,並利用此演算法測試要求(3);
百度百科中對於遺傳演算法的解釋:https://baike.baidu.com/item/遺傳演算法/838140?fr=aladdin。
遺傳演算法(Genetic Algorithms )是基於生物進化理論的原理髮展起來的一種廣為應用的、高效的隨機搜尋與優化的方法。其主要特點是群體搜尋策略和群體中個體之間的資訊交換,搜尋不依賴於梯度資訊。它是在70年代初期由美國密西根( Michigan )大學的霍蘭( Holland )教授發展起來的。1975年霍蘭教授發表了第一本比較系統論述遺傳演算法的專著《自然系統與人工系統中的適應性》(《 Adaptationin Natural and Artificial Systems 》)。遺傳演算法最初被研究的出發點不是為專門解決最優化問題而設計的,它與進化策略、進化規劃共同構成了進化演算法的主要框架,都是為當時人工智慧的發展服務的。迄今為止,遺傳演算法是進化演算法中最廣為人知的演算法。
遺傳火演算法的實施步驟如下(以目標函式求最小為例)。
第一步:初始化 t←0進化代數計數器;T是最大進化代數;隨機生成M個個體作為初始群體P(t);
第二步:個體評價 計算P(t)中各個個體的適應度;
第三步:選擇運算 將選擇運算元作用於群體;
第四步:交叉運算 將交叉運算元作用於群體;
第五步:變異運算 將變異運算元作用於群體,並通過以上運算得到下一代群體P(t + 1);
第六步:終止條件判斷 t≦T:t← t+1 轉到步驟2;t>T:終止 輸出解。
- 遺傳演算法應用步驟:
確定決策變數及各種約束條件,即個體的表現型X和問題的解空間;
建立優化模型 (目標函式最大OR 最小) 數學描述形式 量化方法;
染色體編碼方法;
解碼方法;
個體適應度的量化評價方法 F(x)
設計遺傳運算元;
確定有關執行引數。
參考:https://blog.csdn.net/wangqiuyun/article/details/8847307
4、關鍵程式碼展示
for(int i=1;i<row;i++) {
String Row=Integer.toString(i);
for(int j=1;j<4;j++) {
String Weight=Integer.toString(weight[i][j]);
String Value=Integer.toString(value[i][j]);
String addsql="INSERT INTO table_kp01(tempname,weight,value) VALUES(?,?,?)";
PreparedStatement pst=null;
pst=conn.prepareStatement(addsql);//預編譯SQL
pst.setString(1, Row);
pst.setString(2, Weight);
pst.setString(3, Value);
pst.executeUpdate();//執行SQl語句
}
}
<%@page import="org.apache.log4j.Logger" %>
private static Logger log1=Logger.getLogger(RES);
private static Logger log2=Logger.getLogger(RUN_TIME);
log1.debug("最優解:"+res);
out.println("</br>");//換行標籤
log2.debug("執行時間:"+run_time+"s");
5、結果展示
D{0-1}KP 例項資料集需儲存在資料庫
平臺可動態嵌入任何一個有效的D{0-1}KP 例項求解演算法,並儲存演算法實驗日誌資料;
呼叫演算法結果展示:
人機互動介面要求為GUI介面(WEB頁面、APP頁面都可);
結果展示:
實現結果:
6、PSP
PSP | 任務內容 | 計劃完成所需要的時間(min) | 實際完成所需要的時間(min) |
---|---|---|---|
Planning | 計劃 | 45 | 50 |
Estimate | 估計這個任務需要多少時間,並規劃大致工作步驟 | 50 | 55 |
Development | 開發 | 700 | 800 |
Analysis | 需求分析(包括學習新技術) | 130 | 200 |
Design Spec | 生成設計文件 | 30 | 35 |
Design Review | 設計複審 (和同事稽核設計文件) | 15 | 13 |
Coding Standard | 程式碼規範 | 14 | 18 |
Design | 具體設計 | 260 | 300 |
Coding | 具體編碼 | 300 | 354 |
Code Review | 程式碼複審 | 58 | 60 |
Test | 測試 | 70 | 90 |
Reporting | 報告 | 60 | 70 |
Summer | 任務+總結 | 40 | 60 |
7、小結
兩人進行合作要比一人進行容易得多。經過這次實驗,我發現在真正的結對的情況下,確實會產生1+1>2的情況,因為另一方會從另外一個角度思考,發現對方程式碼的不足並及時指正。但也存在雙方工作沒辦法平均分配,雙方各有擅長的方面,所以在合作時更多的是取長補短,發會合作的優勢。