201971010222-李瑞婷 实验三 结对项目一 《{0-1}KP实例数据集算法实验平台》项目报告
项目 | 内容 |
---|---|
课程班级博客连接 | 2019级卓越工程师班班级博客 |
作业要求链接 | 软件工程结对项目 |
我的课程学习目标 | 1:体验软件项目开发中的两人合作,练习结对编程(Pair programming)。2:掌握Github协作开发软件的操作方法。 |
这个作业在哪些方面帮助我实现学习目标 | 1:结对编程 2:Github协作开发程序的方法 3:代码编写规范与能力提升 |
结对方学号-姓名 | 201971010229-刘转弟 |
结对方本次博客作业链接 | 博客作业链接 |
本项目Github的仓库链接地址 | 地址入口 |
任务一:阅读《现代软件工程—构建之法》第3-4章内容,理解并掌握代码风格规范、代码设计规范、代码复审、结对编程概念;
1:代码风格规范:简明,易读,无二义性
1:缩进:可以使用Tab键以及2、4、8等空格。依据不同是编程语言,使用不同的缩进方式。
2:行宽:对行宽进行同一设置。
3:括号:用括号清楚的表明逻辑优先级。
4:断行与空白的{}行:主要是在多层循环中规范使用。
5:分行:不要把多条语句放在一行上,更不要把多条变量语句放在一行上。
6:命名:命名能够表明变量的类型及相应的语义,简洁易懂。
7:下换线:合理使用来分隔变量名字中的作用域标注和变量的语义。
8:大小写:多个单次组成的变量名,用大小写区分,例如著名的驼峰式命名法。
9:注释:能够很好的解释程序是做什么的(what),以及为什么这样做(why)。
2:代码设计规范
1:函数:能够很好的完成一件事。
2:goto:函数最好有单一的出口,可以使用goto。
3:错误处理:预留足够的时间,使用的方法包括参数处理和断言。
4:c++类的处理:类、classvc.struct、公共/保护/私有成员、数据成员、虚函数、构造函数、析构函数、new和delete、运算符、异常处理、类型继承。
3:代码复审
1:自我复审:用同伴复审的标准来要求自己。不一定最有效, 因为开发者对自己总是过于自信。如果能持之以恒,则对个人有很大好处。
2:同伴复审(最基本):简单易行。
3:团队复审:有比较严格的规定和流程,适用于关键的代码,以及复审后不再更新的代码。覆盖率高——有很多双眼睛盯着程序,但效率可能不高。
4:结对编程
- 两人结对编程,一对程序员肩并肩,平等地,互补地进行开发工作。
任务二:两两自由结对,对结对方《实验二 软件工程个人项目》的项目成果进行评价。
1:对项目博文作业进行阅读并评论
结编同伴 | 201971010229-刘转弟 |
---|---|
评论链接 | 刘转弟软件个人项目 |
评论内容 |
2:克隆结对方项目源码到本地机器,阅读并测试运行代码
对方GitHub仓库地址链接 | liuzhuandi-刘转弟 |
---|
-
克隆
-
数据输入
-
散点图绘制
-
排序
-
代码核查表
项目 | 说明 |
---|---|
概要部分 | |
代码符合需求和规格说明么? | 基本符合,功能大致完成 |
代码设计是否考虑周全? | 考虑比较周全,还可以 |
代码可读性如何? | 尚可 |
代码容易维护么? | 不易维护 |
代码的每一行都执行并检查过了吗? | 是 |
设计规范部分 | |
设计是否遵从已知的设计模式或项目中常用的模式? | 没有 |
有没有硬编码或字符串/数字等存在? | 没有,采用的变量名符合代码规范 |
代码有没有依赖于某一平台,是否会影响将来的移植? | 没有,对移植影响较小 |
开发者新写的代码是否用已有的Library/SDK/Framework中的功能实现? | 是 |
在本项目中是否存在类似的功能可以通过调用而不用全部重新实现? | 不确定 |
有没有无用的代码可以清除? | 有 |
代码规范部分 | |
修改的部分符合代码标准和风格么? | 大致符合 |
具体代码部分 | |
有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常? | 已处理 |
参数传递有无错误,字符串的长度是字节的长度还是字符的长度,是从0开始计数还是从1开始计数 | 无错误;字符的长度;从0开始 |
循环有没有可能出现死循环? | 没有 |
有没有使用断言来保证我们认为不变的条件真的得到满足? | 没有 |
有没有优化的空间? | 有 |
数据结构中有没有用不到的元素? | 有 |
效能 | |
代码的效能如何?最坏的情况是怎么样的? | 效能可以 |
代码中,特别是循环中是否有明显可优化的部分? | 有 |
对于系统和网络的调用是否会超时?如何处理? | 无超时 |
可读性 | |
代码可读性如何?有没有足够的注释? | 关键地方注释少,阅读困难 |
可测试性 | |
代码是否需要更新或创建新的单元测试? | 是 |
-
利用github的Fork、Clone、Push、Pull request、Merge pull request等操作对同伴个人项目仓库的源码进行合作修改
1: Fork
2: Push过程
任务三:采用两人结对编程方式,设计开发一款{0-1}KP 实例数据集算法实验平台。
1:需求分析陈述(3W)
2:软件设计说明
- 遗传算法
在具体解决0-1背包问题的过程中,首先我们看编码问题,对于n个物品,可以用n个二进制位来进行编码,值为1表示该物品加到背包中,值为0表示该物品不加入到背包中,这也是我们一直在用的方法;其次,适应度函数对于优质个体,其值应该较高;而对于劣质个体,其值应该较低。这样我们就可以通过适应度函数的取值来判断个体的优劣。很显然,适应度函数可以定义为一个个体所表示加入到背包中物品的价值总和。接下来选择算子,在这里选择算子的操作流程是:首先保留当前种群中最优的10%的个体;然后在剩下的90%的个体中再添加随机生成的10%的个体;从第二步中的100%的个体中随机选择90%的个体,这样加上第一次选择的10%的个体便可构成新一代的种群。然后交叉算子,种群中的个体两两组队,相互交叉,交叉时相对应位上按照某个可能性(具体的可能性可设置)进行交换值。最后变异算子,每个新的个体,都有可能发生变异(具体的可能性可设置)。一旦这个个体发生变异,那么这个个体上的每一位按照某个可能性(具体的可能性可设置)赋一个随机值。
- GUI
图形用户界面(Graphical User Interface,简称 GUI),是计算机图形学技术的一种,它一般由窗口、下拉菜单或者对话框等图形化的控件组成。用户通过点击菜单栏、按钮或者弹出对话框的形式来实现与机器的交互,我们本次项目主要使用Web页面,提供选择算法解决D{0-1}KP问题,以及显示结果。
3:软件实现
(1)ReadTheFil类 :通过文件路径来创建文件实例,把FileInputStream实例 传递到 BufferedInputStream,目的是能快速读取文件,最后,使用available检查是不是读到了文件末尾。
(2)ScatterDiagram类 :创建二维数组data存储profit价值和height重量,以重量为横轴、价值为纵轴,建立直角坐标系画出散点图。
(3)WeightRatio类 :分别定义int类型数组profit和weight数组将价值和重量存储,因为所给数据全部为int型,再定义比值ratio为double类型,再将其int类型数组强制转换为double进行比值运算,最后运用冒泡排序将比值进行降序排序。
(4)Time类 :使用动态规划算法:在0/1背包问题中,物品i或者被装入背包,或者不被装入背包,设xi表示物品i装入背包的情况,则当xi=0时,表示物品i没有被装入背包,xi=1时,表示物品i被装入背包。
- 图形用户界面(GUI)
点击查看代码
<title>01背包问题_最优解</title>
</select> -->散点图
</a></li>
<li><a href="#">价值,重量比排序</a></li>
<li><a href="#">最优解</a></li>
<li><a href="01_start.jsp">散点图</a></li>
<li><a href="02_start.jsp">价值,重量比排序 </a></li>
<li class="active"><a href="03_start.jsp">最优解 <span
class="sr-only">(current)</span></a></li>
<h2 class="page-header">请输入查询数据</h2>
<ul class="btn-group" role="group">
<li class="btn btn-default"><a href="03_IDKP0_00_DT.jsp"
style="text-decoration: none;">动态规划法</a></li>
</ul>
<ul class="btn-group" role="group">
<li class="btn btn-default"><a href="03_IDKP0_00_HS.jsp"
style="text-decoration: none;">回溯法</a></li>
</ul>
<ul class="btn-group" role="group">
<li class="btn btn-default"><a href="03_IDKP0_00_YC.jsp"
style="text-decoration: none;">遗传算法</a></li>
</ul>
- 数据库访问
点击查看代码
//Product的数据访问类
public class Data1DAO {
//添加一行商品数据,实际上是添加一个Product的对象
public static int insert(Data1 p) throws SQLException{
//1.连接数据库 2.构造SQL语句 3.(通过)预编译SQL语句 4.设置参数 5.执行SQL
Connection conn = dbtool.getConnection();
String insert = "insert into table_product(id v weight na ratio)"
+"values(?,?,?,?,?)";
PreparedStatement pst = conn.prepareStatement(insert);
pst.setString(1,p.getV());
pst.setInt(2, p.getId());
pst.setString(3, p.getWeight());
pst.setString(4, p.getNa());
pst.setString(5, p.getRatio());
int result = pst.executeUpdate();
return result;
}
//删除一行数据
public static void delete(int id){
Connection conn = dbtool.getConnection();
String delete = "delete from data1"
+"where id=+'"+id+"'" ;
}
//查找一个
public static Data1 findProuduct(int id){
//ResultSet rs;
//从结果集rs中获得各列的值,用这些值构造一个Product对象
return null;
}
//查找多个
public static List<Data1> findAll(){
//ResultSet rs;
//从结果集rs中获得各列的值,用这些值构造一个Product对象
return null;
}
}
- 遗传算法
点击查看代码
//遗传算法
public class GeneticAlgorith {
private static final Chromosome Exception = null;
long timeStart = System.currentTimeMillis();
public List<Chromosome> population=new ArrayList<Chromosome>();//存放所有的种群基因
private int popSize; //种群规模N
private int chromoLength;//每条染色体数目m;
private double mutationRate=0.01;//基因突变概率pm
private double crossoverRate=0.6;//交叉概率pc
private int bagMax=1000;
private int generation;//种群代数t
private int iterNum=10000;//最大迭代次数
// private int stepmax=3;//最长步长
private int [] charge={408,921,1329,11,998,1009,104,839,943,299,374,673,703,954,1657,425,950,1375,430,541,971,332,483,815,654,706,1360,956,992,1948};
private int [] weight={508,1021,1321,111,1098,1196,204,939,1107,399,474,719,803,1054,1781,525,1050,1362,530,641,903,432,583,894,754,806,1241,1056,1092,1545};
private double[] density=new double[50];
private Chromosome nowGenome;
private Chromosome bestFit; //最好适应度对应的染色体
private Chromosome iterBestFit;//全局最优染色体
private double bestFitness;//种群最大适应度
private double worstFitness;//种群最坏适应度
private double averageFitness;
/*
初始化种群
*/
public void init(){
for(int i=0;i<charge.length;i++){
density[i]=charge[i]/weight[i];
}
for(int i=0;i<popSize;i++){
Chromosome g=new Chromosome(50);
changeGene(g);
population.add(g);
/*
计算种群适应度
*/
public void caculteFitness(){
bestFitness=population.get(0).getFitness();
worstFitness=population.get(0).getFitness();
totalFitness=0;
for (Chromosome g:population) {
//changeGene(g);
setNowGenome(g);
if(g.getFitness()>bestFitness){
setBestFitness(g.getFitness());
if(y<bestFitness){
y=g.getFitness();
}
setIterBestFit(g);
}
if(g.getFitness()<worstFitness){
worstFitness=g.getFitness();
}
totalFitness+=g.getFitness();
}
averageFitness = totalFitness / popSize;
//因为精度问题导致的平均值大于最好值,将平均值设置成最好值
averageFitness = averageFitness > bestFitness ? bestFitness : averageFitness;
}
/*
遗传算法GA流程
*/
public void geneticAlgorithProcess(){
generation=1;
init();
while(generation<iterNum){
evolve();
print();
generation++;
}
}
4:程序运行
- 界面登录
- 后台页面
- 散点图展示
- 排序
- 算法选择及最优解
- 具体算法求解(以 遗传算法.为例)
- 数据库连接及数据导入
5:结对编程
- 交流
6:项目PSP
PSP | 任务内容 | 计划完成需要的时间min | 实际完成需要的时间min |
---|---|---|---|
Planning | 计划 | 15 | 10 |
- Estimate | - 估计这个任务需要多少时间,并规划大致工作步骤 | 15 | 10 |
Development | 开发 | 840 | 940 |
- Analysis | - 需求分析(包括学习新技术) | 30 | 25 |
- Design Spec | - 生产设计文档 | 20 | 30 |
- Design Review | - 设计复审 | 10 | 10 |
- Coding Standard | - 代码规范 | 30 | 45 |
- Coding | - 具体编码 | 600 | 650 |
- Code Review | - 代码复审 | 30 | 60 |
- Test | - 测试(自我测试,修改代码,提交修改) | 120 | 120 |
Reporting | 报告 | 90 | 71 |
- Test Report | - 测试报告 | 50 | 25 |
- Size Measurement | - 计算工作量 | 10 | 16 |
- Postmortem & Process Improvement Plan | - 事后总结,并提出过程改进计划 | 30 | 30 |