201971010245-王亞亞 實驗三 結對專案—《{0-1}KP 例項資料集演算法實驗平臺》專案報告
專案 | 內容 |
---|---|
課程班級部落格連結 | https://edu.cnblogs.com/campus/xbsf/2019nwnucs |
這個作業要求連結 | https://edu.cnblogs.com/campus/xbsf/2019nwnucs/homework/12560 |
我的課程學習目標 | 1. 體驗軟體專案開發中的兩人合作,練習結對程式設計 2. 掌握Github協作開發程式的操作方法。 3.閱讀《現代軟體工程—構建之法》學習程式碼規範等知識 4. 學習遺傳演算法並進行問題求解。 |
這個作業在哪些方面幫助我實現學習目標 | 1.熟悉了軟體工程結對程式設計 2.掌握Github克隆結對方專案 3.學習了程式碼風格規範、程式碼設計規範、程式碼複審等知識 |
結對方學號-姓名 | 201971010242-王凱英 |
結對方本次部落格作業連結 | https://www.cnblogs.com/201971010242wang/p/16043089.html |
本專案Github的倉庫連結地址 | https://github.com/201971010245/-0-1-kp |
1. 實驗目的與要求
(1)體驗軟體專案開發中的兩人合作,練習結對程式設計(Pair programming)。
(2)掌握Github協作開發軟體的操作方法。
2. 實驗內容和步驟
任務1:閱讀《現代軟體工程—構建之法》第3-4章內容,理解並掌握程式碼風格規範、程式碼設計規範、程式碼複審、結對程式設計概念;
1.程式碼風格規範:
程式碼風格規範包括命名規範,程式碼展示風格的規範(縮排、空格、換行),控制語句的規範以及程式碼註釋的規範,好的程式碼風格規範可以讓其他人更好的理解。它的原則是:簡明,易讀,無二義性。
- 四個空格的縮排
- 每個{}獨佔一行
- 不要把多個變數定義在一行上
- 一個型別的成員變數用同一型別命名
- 所有的型別/類/函式名
- 註釋是為了解釋程式做什麼(What),為什麼這麼做(Why),以及要特別注意的地方,只用ASCII字元,不要用中文
2.程式碼設計規範:
- 函式:只做一件事,並且要做好
- 單一出口
- 不要在建構函式中做複雜的操作,簡單初始化所有的資料成員即可
3.程式碼複審:
看程式碼是否在程式碼規範的框架內正確地解決了問題、長遠的問題;
- 修改之後,有沒有別的功能會受影響;
- 專案中還有別的地方需要類似的修改嗎;
- 有沒有留下足夠的說明,讓將來維護程式碼時不會出現問題;
- 對於修改,是否需要告知成員;
- 導致問題的根本原因是什麼?以後如何能自動避免這樣的情況再次出現。
結對程式設計
結對程式設計是一種敏捷軟體開發的方法,兩個程式設計師在一個計算機上共同工作。一個人輸入程式碼,而另一個人審查他輸入的每一行程式碼。輸入程式碼的人稱作駕駛員,審查程式碼的人稱作觀察員。兩個程式設計師經常互換角色。
在結對程式設計中,觀察員同時考慮工作的戰略性方向,提出改進的意見,或將來可能出現的問題以便處理。這樣使得駕駛者可以集中全部注意力在完成當前任務的“戰術”方面。觀察員當作安全網和指南。結對程式設計對開發程式有很多好處。比如增加紀律性,寫出更好的程式碼等。
結對程式設計是極端程式設計的組成部分。
任務2:兩兩自由結對,對結對方《實驗二 軟體工程個人專案》的專案成果進行評價,具體要求如下:
(1)對專案博文作業進行閱讀並進行評論,評論要點包括:博文結構、博文內容、博文結構與PSP中“任務內容”列的關係、PSP中“計劃共完成需要的時間”與“實際完成需要的時間”兩列資料的差異化分析與原因探究,將以上評論內容釋出到部落格評論區。
結對方部落格連結:王凱英的部落格
結對方Github專案倉庫連結:王凱英Github專案倉庫連結
部落格評論:
(2)克隆結對方專案原始碼到本地機器,閱讀並測試執行程式碼,參照《現代軟體工程—構建之法》4.4.3節核查表複審同伴專案程式碼並記錄。
- 克隆對方程式碼到本地機器
- 程式碼核查表
內容 | 完成效果 |
---|---|
是否可正確讀入實驗資料檔案的有效D{0-1}KP資料 | 程式碼實現了從本地讀取資料,符合需求且比較容易維護 |
是否能夠繪製任意一組D{0-1}KP資料以重量為橫軸、價值為縱軸的資料散點圖 | 可根據讀入的不同資料準確繪製以重量為橫軸、價值為縱軸的資料散點圖,符合實驗要求。 |
是否對一組D{0-1}KP資料按項集第三項的價值:重量比進行非遞增排序 | 對不同的資料可以進行選擇並對其進行能夠對一組D{0-1}KP資料按項集第三項的價值:重量比進行非遞增排序;但相關部分程式碼可讀性較差,存在較多問題。 |
是否自主選擇動態規劃演算法、回溯演算法求解指定D{0-1} KP資料的最優解和求解時間 | 程式碼中選擇動態規劃演算法任意選擇一組資料並求解了這組資料的最優解和求解時間,求解時間也是按照以秒為單位,符合實驗要求 |
是否將任意一組D{0-1} KP資料的最優解、求解時間和解向量可儲存為txt檔案或匯出EXCEL檔案。 | 完成了任意一組D{0-1} KP資料的最優解、求解時間和解向量可儲存為txt檔案或匯出EXCEL檔案儲存在本地。 |
程式碼規範 | 專案中大部分程式碼是符合程式碼標準和風格的,但對於返回函式沒有進行檢查 |
程式碼可讀性 | 程式碼可讀性較強,在有些較難理解部分進行了詳細的註釋使得程式的可讀性增強。 |
1)概要部分
a.程式碼符合需求和規格說明
b.程式碼設計沒有考慮周全,有很多程式碼使用的很不合適。
c.程式碼可讀性還性吧,不過有的還存在很多問題。
d.程式碼比較容易維護。
e.程式碼的每一行都執行了,都檢查了。
2)設計規範部分
a.程式碼遵循了已知的設計模式和在專案中的常用模式, 學習了很多知識。
b.我程式碼設計中有字串和數字的存在。
c.程式程式碼沒有依賴於某一平臺,從Win32移植到Win64上沒有出現很大的問題。
d.在本程式中類似的功能差不多都可以呼叫而不用全部重新來實現。
e.有無用的程式碼可以刪除,在我的抽籤程式中,我對於按組抽籤中的新增人員姓名進行了編碼,實際上是不需要的,因為一個學號就做夠啦,而且還有窗體控制元件的功能實現。
3)程式碼規範部分
a.修改的部分有很多地方是符合程式碼標準和風格的,但是有也有程式碼是沒有符合標準和風格的。
4)具體程式碼部分
a.在抽籤程式中對錯誤進行了處理,在實現號碼滾動的程式碼上出現了錯誤,只能實現程式碼中的數字,而不能隨機的進行輸入數字。對於呼叫的外部函式,檢查了返回值。
b.引數傳遞無錯誤,字串的長度是位元組的長度,是雙位元組,是以1開始計數
c.Switch語句的用的很好,沒有出現死迴圈
d.沒有使用斷言(Assert)來保證我們認為不變的條件真的滿足
f.對資源的利用,是在C#書上借鑑的,記憶體、檔案、各種GUI資源、資料庫訪問的連線沒有可能導致資源洩露,有可能優化
e.資料結構中有很的元素是沒有用到的。
5)效能
a.程式碼中,特別是迴圈中沒有明顯可優化的部分。
b.對於系統和網路呼叫會超時,可以等待一會。
6)可讀性
程式碼可讀性很易懂,沒有足夠的註釋,程式碼量很少。
7) 可測試性
a.程式碼需要更新和建立新的單元測試。
b.可以針對部分功能的實現對程式碼進行進一步改進或建立新的單元測試。
(3)依據複審結果嘗試利用github的Fork、Clone、Push、Pull request、Merge pull request等操作對同伴個人專案倉庫的原始碼進行合作修改。
fork:從別人釋出的專案上覆制一個過來,相當於一個分支;專案複製到自己的個github中,於是本地就有了一個倉庫,假設名字為A;
clone: 從自己的github上把fork過來的複製到本地,這樣本地就有了一個專案A1;
push:當你在A1中進行修改進行開發後,最後同步到你的github上的倉庫中;
pull request:你把自己github中的已經修改的內容申請同步到最初那個開發者的專案中。
克隆到本地
關聯原始倉庫
PUSH
任務3:兩兩採用兩人結對程式設計方式,設計開發一款D{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);
在實驗過程中,此次實驗要求的技術與我在此之前的掌握的技術有一定差距。所以我複習了大學三年級第一學期在《演算法設計與分析》課程中學習到的動態規劃演算法與回溯演算法求解0/1揹包問題的內容,循序漸進,推進實驗的程序。
1、動態規劃演算法
動態規劃演算法的核心思想是:
將大問題劃分為小問題進行解決,從而一步一步獲得最優解的處理演算法。
動態規劃演算法與分治演算法類似,其基本思想也是將代求問題分解成若干子問題,先求解子問題,然後從這些子問題的解得到原問題的解。
與分治演算法不同的是,適合於動態規劃求解的問題,經分解得到的子問題往往不是互相獨立的,即下一個子階段的求解過程是建立在上一個子階段的解的基礎上,進行進一步的求解。
2、回溯演算法
顧名思義,回溯法一個很顯著的特徵就是回溯,即在處理完某種情況或出現不能繼續進行的情況時,要退回到之前的某個“交叉口”,處理另一種可能。
回溯法是一種非常有效的方法,有“通用的解題法”之稱。它有點像窮舉法,但是更帶有跳躍性和系統性,他可以系統性的搜尋一個問題的所有的解和任一解。回溯法採用的是深度優先策略。通常,回溯法會定義一個解空間,這個解空間通常是以圖或樹的形式呈現出來的。揹包問題的解空間是樹的形式,屬於深度優先搜尋。
回溯法在確定瞭解空間的結構後,從根結點出發,以深度優先的方式搜尋整個解空間,此時根結點成為一個活結點,並且成為當前的擴充套件結點。每次都從擴充套件結點向縱向搜尋新的結點,當演算法搜尋到瞭解空間的任一結點,先判斷該結點是否肯定不包含問題的解(是否還能或者還有必要繼續往下搜尋),如果確定不包含問題的解,就逐層回溯;否則,進入子樹,繼續按照深度優先的策略進行搜尋。當回溯到根結點時,說明搜尋結束了,此時已經得到了一系列的解,根據需要選擇其中的一個或者多個解即可。
回溯法解決問題一般分為三個步驟:
(1)針對所給問題,定義問題的解空間;
(2)確定易於搜尋的解空間結構;
(3)以深度優先的方式搜尋解空間
軟體實現及核心功能程式碼展示
軟體包括哪些類,這些類分別負責什麼功能,他們之間的關係怎樣?類內有哪些重要的方法,關鍵的方法是否需要畫出流程圖?
專案資料夾基本部分註釋:
程式碼展示:
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語句
}
}
(3)平臺可動態嵌入任何一個有效的D{0-1}KP 例項求解演算法,並儲存演算法實驗日誌資料;
呼叫演算法結果展示:
演算法實驗日誌資料結果展示:
演算法實驗日誌資料部分程式碼:
<%@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");
遺傳演算法概述:
遺傳演算法(Genetic Algorithm,GA)是進化計算的一部分,是模擬達爾文的遺傳選擇和自然淘汰的生物進化過程的計算模型,是一種通過模擬自然進化過程搜尋最優解的方法。該演算法簡單、通用,魯棒性強,適於並行處理。
遺傳演算法的基本流程
通過隨機方式產生若干由確定長度(長度與待求解問題的精度有關)編碼的初始群體;
通過適應度函式對每個個體進行評價,選擇適應度值高的個體參與遺傳操作,適應度低的個體被淘汰;
經遺傳操作(複製、交叉、變異)的個體集合形成新一代種群,直到滿足停止準則(進化代數GEN>=?);
將後代中變現最好的個體作為遺傳演算法的執行結果。
其中,GEN是當前代數;M是種群規模,i代表種群數量。
此次結對作業的PSP
任務內容 | 計劃共完成需要的時間/分鐘 | 實際完成需要的時間/分鐘 |
---|---|---|
計劃總時長 | 1180 | 2050 |
任務一 | 50 | 55 |
閱讀《現代軟體工程—構建之法》第3-4章 | 50 | 55 |
任務二 | 320 | 400 |
對專案博文作業進行閱讀並進行評論 | 20 | 20 |
克隆結對方專案原始碼到本地機器,閱讀並測試執行程式碼 | 100 | 120 |
依據複審結果用github的Fork、Clone、Push等操作對同伴個人專案倉庫的原始碼進行合作修改 | 200 | 260 |
任務3 | 810 | 1595 |
D{0-1}KP 例項資料集儲存在資料庫 | 40 | 60 |
將資料庫資料讀取出來 | 40 | 70 |
用讀出來的資料繪製散點圖並顯示在人機互動頁面 | 60 | 270 |
動態規劃演算法結果顯示在前端 | 60 | 120 |
回溯演算法結果顯示 | 40 | 75 |
將資料項顯示在前端,按其第三項進行排序並顯示 | 80 | 100 |
平臺可動態嵌入任何一個有效的D{0-1}KP 例項求解演算法,並儲存演算法實驗日誌資料 | 250 | 400 |
人機互動介面要求為GUI介面 | 40 | 50 |
查閱資料,設計遺傳演算法求解D{0-1}KP,並利用此演算法測試要求 | 200 | 450 |
此次專案總結
這次的實驗我們嘗試了結對程式設計,通過結對程式設計我們可以一起去交流學習。結對程式設計的效果是真的挺大的,通過結對程式設計我們共同合作,能夠想到一些對方沒有考慮地方,可以分享知識、共同解決遇到的問題。兩個人合作完成一個專案,要比起自己單獨去完成效果好很多,不僅會減輕雙方的工作量,還可以在合作中最大化發揮自己的優點,同時也可以從對方身上學到很多自己不擅長的技術,互相彌補,共同進步。而且通過這次的結對程式設計,我們學會了合作學習、交流,知道怎麼團隊工作。