201871010121-王方- 实验三 结对项目-《D{0-1}实例数据集算法实验平台》项目报告
项目 | 内容 |
---|---|
课程班级博客链接 | 2018级计算机科学与技术1班(师范) |
这个作业要求链接 | 作业要求 |
我的课程学习目标 | 1.体验软件项目开发中的两人合作,练习结对编程 2.掌握Github协作开发程序的操作方法; |
这个作业在哪些方面帮助我实现学习目标 | 1.了解了Github发布软件项目的操作方法; 2. 第二次制作PSP流程,对个人软件项目开发流程的特点和基础在掌握的基础上有了更深入的了解; 3.通过自己学习了遗传算法,通过实验任务对背包问题再次掌握,并学会使用相关算法解决背包问题; 4.切身体验结对编程的优缺点 |
结对方学号-姓名 | 20187101028-王亚涛 |
结对方本次博客作业链接 | 王亚涛 |
本项目Github的仓库链接地址 | github仓库 |
-
一、实验目的和要求
- (1)体验软件项目开发中的两人合作,练习结对编程(Pair programming)。
- (2)掌握Github协作开发程序的操作方法。
-
二、实验内容和步骤
任务1:
-
第四章讲的是两人合作。具体讲的是两人合作间注意的事项、细节。有:代码的规范、代码风格的规范、代码设计规范、代码的复审和结对编程。我认为前面提到的四点:代码的规范、代码风格的规范、代码设计规范和代码的复审都是为最后的一个内容结对编程做准备的。结对编程非常注意个人的习惯细节等方面,自己写出来的代码不是只给自己看而把代码写的一团糟,还要能让队友或旁人看,要让他们有一种整洁的感觉。在两人合作的初期,代码的正确性也没这种习惯的重要性大。所以应该先遵循某种约定或规范培养良好的习惯,从而产生默契。
-
代码风格规范:
主要是文字上的规定。代码风格的原则是:简明、易读、无二义性,包括对于缩进、行宽、括号、分行、命名、下划线、注释、大小写以及断行与空白的{}行的处理;缩进限定为100字符;复杂的条件表达式中,用括号表示逻辑优先级;有清晰的断行和分行;命名应该遵循规则,简洁易懂。 -
代码设计规范:
牵扯到程序设计、模块之间的关系、设计模式等。比如针对函数,他的最重要的原则就是:只做一件事,并且要做好。可以使用goto实现单一的出口。还有错误处理方面的一些内容,比如断言的正确使用等规范。程序的绝大多数功能,都在程序中实现,函数的原则是只做好一件事;使用goto语句使得程序有单一的出口;错误处理的时间更甚于程序功能的实现;所有的参数都要验证其正确性,验证正确性使用断言; -
代码复审:
- 看代码是否在代码规范的框架内正确地解决了问题。代码复审的三种形式:自我复审、同伴复审、团队复审。
- 自我复审:自己 VS 自己,用同伴复审的标准来要求自己。不一定最有效,因为开发者对自己总是过于自信,如果能持之以恒,则对个人有很大好处。
- 同伴复审:复审者 VS 开发者,简便易行,最基本的复审手段。
- 团队复审:团队 VS 开发者,有比较严格的规定和流程,适用于关键的代码,以及复审后不再更新的代码,覆盖率高——有很多双眼睛盯着程序,但效率可能不高。
-
代码复审的目的:
- 找出代码的错误,比如编码错误和不符合团队代码规范的地方。
- 发现逻辑错误,程序可以编译通过,但是代码的逻辑是错误的。
- 发现算法错误,比如使用的算法不够优化,边界没有处理好等。
- 发现潜在的错误和回归性错误——当前的修改导致以前修复的缺陷又重新出现。
- 发现可能需要改进的地方。
- 教育(互相教育)开发人员,传授经验,让更多的成员熟悉项目各部分的代码,同时熟悉和应用领域相关的实际知识。
-
结对编程:
- 是指一起分析,一起设计,一起写测试用例,一起做单元测试,一起做集成测试,一起写文档等,在结对编程中,因为有随时的复审和交流,程序各方面的质量取决于一对程序员中各方面水平较高的那一位。结对编程有以下好处:
- 在开发层次,结对编程能提供更好的设计质量和代码质量,两人合作解决问题的能力更强。两人合作,还有相互激励的作用,工程师看到别人的思路和技能,得到实时的讲解,受到激励,从而努力提高自己的水平。
- 对开发人员自身来讲,结对工作能带来更多的信心,高质量的产出能带来更高的满足感。
- 在企业管理层次上,结对能更有效地交流、相互学习和传递经验,分享知识,能够更好地应对人员流动。
任务2:
- (1)对结对队友《实验二 软件工程个人项目》的项目成果进价链接:王亚涛
任务3:
- (1)需求分析:
- 遗传算法:
遗传算法是从代表问题可能潜在的解集的一个种群(population)开始的,而一个种群则由经过基因(gene)编码的一定数目的个体(individual)组成。每个个体实际上是染色体(chromosome)带有特征的实体。
基因型(genotype):性状染色体的内部表现。
表现型(phenotype):染色体决定的性状的外部表现,或者说,根据基因型形成的个体的外部表现。
进化(evolution):种群逐渐适应生存环境,品质不断得到改良。生物的进化是以种群的形式进行的。
适应度(fitness):度量某个物种对于生存环境的适应程度。
选择(selection):以一定的概率从种群中选择若干个个体。一般,选择过程是一种基于适应度的优胜劣汰的过程。
复制(reproduction):细胞分裂时,遗传物质DNA通过复制而转移到新产生的细胞中,新细胞就继承了旧细胞的基因。
交叉(crossover):两个染色体的某一相同位置处DNA被切断,前后两串分别交叉组合形成两个新的染色体。也称基因重组或杂交。
变异(mutation):复制时可能(很小的概率)产生某些复制差错,变异产生新的染色体,表现出新的性状。
编码(coding):DNA中遗传信息在一个长链上按一定的模式排列。遗传编码可看作从表现型到基因型的映射。
解码(decoding):基因型到表现型的映射。
个体(individual):指染色体带有特征的实体。
种群(population):个体的集合,该集合内个体数称为种群的大小。
遗传算法的特点和应用
遗传算法是一类可用于复杂系统优化的具有鲁棒性的搜索算法,与传统的优化算法相比,具有以下特点:- 以决策变量的编码作为运算对象。
遗传算法是使用决策变量的某种形式的编码作为运算对象。这种对决策变量的编码处理方式,使得我们在优化计算中可借鉴生物学中染色体和基因等概念,可以模仿自然界中生物的遗传和进化激励,也可以很方便地应用遗传操作算子。 - 直接以适应度作为搜索信息。
遗传算法仅使用由目标函数值变换来的适应度函数值就可确定进一步的搜索范围,无需目标函数的导数值等其他辅助信息。直接利用目标函数值或个体适应度值也可以将搜索范围集中到适应度较高部分的搜索空间中,从而提高搜索效率。 - 使用多个点的搜索信息,具有隐含并行性。
遗传算法从由很多个体组成的初始种群开始最优解的搜索过程,而不是从单个个体开始搜索。对初始群体进行的、选择、交叉、变异等运算,产生出新一代群体,其中包括了许多群体信息。这些信息可以避免搜索一些不必要的点,从而避免陷入局部最优,逐步逼近全局最优解。
综上,由于遗传算法的整体搜索策略和优化搜索方式在计算时不依赖于梯度信息或其他辅助知识,只需要求解影响搜索方向的目标函数和相应的适应度函数,所以遗传算法提供了一种求解复杂系统问题的通用框架。它不依赖于问题的具体领域,对问题的种类有很强的鲁棒性,所以广泛应用于各种领域,包括:函数优化、组合优化、生产调度问题、自动控制、机器人学、图像处理、人工生命、遗传编程、机器学习等。
- 以决策变量的编码作为运算对象。
- 遗传算法:
- (2)解题思路:
利用遗传算法时,可以随机生成一个长度为50的0-1序列,其中1表示对应位置的物品装进背包,0表示对应物品不装进背包,需要注意的是,生成的序列有可 能 ,超过背包的总重量,不满足约束条件,此时需要对序列进行操作。可行的操作有两种,第一种是对于不满足约束条件的序列进行抛弃,第二种是对其进行贪心算子变换,具体操作如下:
a.对所有 x_1=1 的物品,按它们的价值密度排序,形成队列b(i);
b.依次放入价值密度最大的物品,并判断是否有超出背包限定的范围;
c.如果超出,则将价值密度序列中从这个位置之后的所有商品置0;
-
`import java.util.Random;
public class Chromosome {
public boolean[] gene;
private int fitness;
private int bag=1000;
public int getFitness() {
return fitness;
}
public void setFitness(int fitness) {
this.fitness = fitness;
}
/*
构造染色体
*/
public Chromosome(int n){
if (n<0){
return;
}
initSize(n);
for(int i=0;i<n;i++){
gene[i]=Math.random()>=0.5;
}
getFitness();
}
public Chromosome(){
}
public void initSize(int n){
if (n<0){
return;
}
this.gene=new boolean[n];
}
/*
染色体变异
*/
public void mutation(int size,double rate){
Random random=new Random();
for(int i=0;i<size;i++){
if(random.nextDouble()<rate){
boolean t=gene[i];
t=!t;
gene[i]=t;
}
}
}
}`
(1)类的设计
`class Global {
publicfinal static int M =200; //种群的规模
publicfinal static int T = 1000; //遗传的最大代数
publicfinal static double pc = 0.8; //交叉率
publicfinal static double pv = 0.05; //变异率
}
class MaxValue{
publicstatic int[] have = null; //最大解选择到的物品
publicstatic int max_value = 0; //最大解的价值
}
public class GasolvePackage`
2)类的功能:
`Global类中定义的相当于全局变量。
MaxValue类中记录最优解,have数组记录选择的到的物品,max_value记录最优解得价值
GasolvePackage类有遗传算法的各种函数`
- (2) 结对小伙伴
- (3)此次作业所制定PSP
PSP 各个阶段 | 自己预估的时间(分钟) | 实际的记录(分钟) |
---|---|---|
计划: | 60 | 60 |
开发 : | 1000 | 1400 |
(1)需求分析 | 100 | 150 |
(2)生成设计文档 | 60 | 50 |
(3)设计复审 | 0 | 0 |
(4)代码规范 | 30 | 60 |
(5)具体设计 | 720 | 600 |
(6)具体编码 | 500 | 720 |
(7)代码复审 | 50 | 60 |
(8)测试 | 60 | 90 |
报告: | 90 | 90 |
(1)测试报告 | 60 | 60 |
(2)计算工作量 | 30 | 30 |
总结并改进 | 30 | 60 |
(4)我个人觉得两人合作能够带来1+1>2的效果。经过这次实验,我觉得结对项目的好处在于在项目实施过程中两个人会更容易发现对方代码的不足并及时指正,在合作时可以取长补短,互相借鉴,互相学习,发挥合作学习的优势,学习效率比起一个人要快的多,这种应该就是1+1>2的体会吧。