201871030115-康旭 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

项目 内容
课程班级博客链接 18卓越班
这个作业要求链接 实验三结对编程要求
我的课程学习目标 (1)体验软件项目开发中的两人合作,练习结对编程(Pair programming);
(2)掌握Github协作开发程序的操作方法。
这个作业在哪些方面帮助我实现学习目标 (1)通过与结对方配合实现该项目,从而熟悉了结对编程的方法;
(2)熟悉了通过Github协作开发程序的操作方法。
结对方学号-姓名 201871030124-王超怀
结对方本次博客作业链接 结对方博客连接
本项目Github的仓库链接地址 github仓库链接

实验内容

任务1:阅读《现代软件工程—构建之法》第3-4章内容,理解并掌握代码风格规范、代码设计规范、代码复审、结对编程概念

  • 代码规范
    • 代码风格规范:主要是文字上的规定。

      • 原则:简明、易读、无二义性。
      • 主要包含:缩进、行宽、括号、断行与空白的{}行、分行、命名、下划线、大小写、注释等。
    • 代码设计规范:牵涉到程序设计、模块之间的关系、设计模式等方方面面的通用原则。

      • 这部分主要描述了错误处理:参数的处理、断言以及如何处理C++的类。
    • 代码复审

      • 定义:看代码是否在代码规范的框架内正确地解决了问题。

      • 形式

        名称 形式
        自我复审 自己vs自己 用同伴复审的标准来要求自己。不一定最有效,因为开发者对自己总是过于自信。如果能持之以恒,则对个人有很大好处
        同伴复审 复审者vs开发者 简便易行
        团队复审 团队vs开发者 有比较严格的规定和流程,适用于关键的代码,以及复审后不再更新的代码覆盖率高一有很多双眼睛盯着程序,但效率可能不高( 全体人员都要到会)
      • 目的:
        • 找出代码的错误。如:

          a. 编码错误,比如一些能碰巧骗过编译器的错误。

          b. 不符合项目组的代码规范的地方。

        • 发现逻辑错误,程序可以编译通过,但是代码的逻辑是错的。

        • 发现算法错误,比如使用的算法不够优化。

        • 发现潜在的错误和回归性错误——当前的修改导致以前修复的缺陷又重新出现。

        • 发现可能改进的地方。

        • 教育(互相教育)开发人员,传授经验,让更多的成员熟悉项目各部分的代码,同时熟悉和应用领域相关的实际知识。

      • 要求:
        • 代码必须成功地编译。
        • 程序员必须测试过代码。
        • 在面对面的复审中,一般是开发者控制流程,讲述修改的前因后果。但是复审者有权在任何时候打断叙述,提出自己的意见。
        • 复审者必须逐一提供反馈意见。
        • 开发者必须负责让所有的问题都得到满意的解释或解答,或者在TFS中创建新的工作项以确保这些问题会得到处理。
        • 对于复审的结果,双方必须达成一致的意见。
    • 结对编程
      • 概念:在结对编程模式下,一对程序员肩并肩地、平等地、互补地进行开发工作。两个程序员并排坐在一台电脑前,面对同一个显示器,使用同一个键盘,同一个鼠标一起工作。他们一起分析,一起设计,一起写测试用例,一起编码,一起单元测试,一起集成测试,一起写文档等。
      • 优点:每人在各自独立设计、实现软件的过程中不免要犯这样那样的错误。在结对编程中,因为有随时的复审和交流,程序各方面的质量取决于一对程序员中各方面水平较高的那一位。这样,程序中的错误就会少得多,程序的初始质量会高很多,这样会省下很多以后修改、测试的时间。具体地说,结对编程有如下的好处:
        • 在开发层次,结对编程能提供更好的设计质量和代码质量,两人合作能有更强的解决问题的能力。
        • 对开发人员自身来说,结对工作能带来更多的信心,高质量的产出能带来更高的满足感。
        • 在心理上, 当有另一个人在你身边和你紧密配合, 做同样一件事情的时候, 你不好意思开小差, 也不好意思糊弄。
        • 在企业管理层次上,结对能更有效地交流,相互学习和传递经验,能更好地处理人员流动。因为一个人的知识已经被其他人共享。
      • 影响他人的方式:断言,桥梁,说服,吸引。

任务2:两两自由结对,对结对方《实验二 软件工程个人项目》的项目成果进行评价

  • 具体要求:
    • 对项目博文作业进行阅读并进行评论,评论要点包括:博文结构、博文内容、博文结构与PSP中“任务内容”列的关系、PSP中“计划共完成需要的时间”与“实际完成需要的时间”两列数据的差异化分析与原因探究,将以上评论内容发布到博客评论区。
    • 克隆结对方项目源码到本地机器,阅读并测试运行代码,参照《现代软件工程—构建之法》4.4.3节核查表复审同伴项目代码并记录。
    • 依据复审结果尝试利用github的Fork、Clone、Push、Pull request、Merge pull request等操作对同伴个人项目仓库的源码进行合作修改。
  • 结对方学号-姓名:201871030124-王超怀

  • 结对方博客https://www.cnblogs.com/WangOwO/p/14600994.html

  • 结对方github地址https://github.com/OwOWang/WangSoftware

任务3:采用两人结对编程方式,设计开发一款D{0-1}KP 实例数据集算法实验平台

  • 需求分析:
    • 平台基础功能:实验二 任务3。
    • D{0-1}KP 实例数据集需存储在数据库。
    • 平台可动态嵌入任何一个有效的D{0-1}KP 实例求解算法,并保存算法实验日志数据。
    • 人机交互界面要求为GUI界面。
    • 查阅资料,设计遗传算法求解D{0-1}KP,并利用此算法测试要求。
    • 附加功能:除(1)-(5)外的任意有效平台功能实现。
  • 遗传算法核心代码:
    // 计算种群中各个个体的累积概率,前提是已经计算出各个个体的适应度fitness[max],作为赌轮选择策略一部分,Pi[max]
    	void countRate() {
    		int k;
    		double sumFitness = 0;// 适应度总和
     
    		int[] tempf = new int[scale];
     
    		for (k = 0; k < scale; k++) {
    			tempf[k] = fitness[k];
    			sumFitness += tempf[k];
    		}
     
    		Pi[0] = (float) (tempf[0] / sumFitness);
    		for (k = 1; k < scale; k++) {
    			Pi[k] = (float) (tempf[k] / sumFitness + Pi[k - 1]);
    		}
    	}
     
    	// 挑选某代种群中适应度最高的个体,直接复制到子代中
    	// 前提是已经计算出各个个体的适应度Fitness[max]
    	public void selectBestGh() {
    		int k, i, maxid;
    		int maxevaluation;
     
    		maxid = 0;
    		maxevaluation = fitness[0];
    		for (k = 1; k < scale; k++) {
    			if (maxevaluation < fitness[k]) {
    				maxevaluation = fitness[k];
    				maxid = k;
    			}
    		}
     
    		if (bestLength < maxevaluation) {
    			bestLength = maxevaluation;
    			bestT = t;// 最好的染色体出现的代数;
    			for (i = 0; i < LL; i++) {
    				bestTour[i] = oldPopulation[maxid][i];
    			}
    		}
     
    		// 复制染色体,k表示新染色体在种群中的位置,kk表示旧的染色体在种群中的位置
    		copyGh(0, maxid);// 将当代种群中适应度最高的染色体k复制到新种群中,排在第一位0
    	}
     
    	// 复制染色体,k表示新染色体在种群中的位置,kk表示旧的染色体在种群中的位置
    	public void copyGh(int k, int kk) {
    		int i;
    		for (i = 0; i < LL; i++) {
    			newPopulation[k][i] = oldPopulation[kk][i];
    		}
    	}
     
    	// 赌轮选择策略挑选
    	public void select() {
    		int k, i, selectId;
    		float ran1;
    		for (k = 1; k < scale; k++) {
    			ran1 = (float) (random.nextInt(65535) % 1000 / 1000.0);
    			// System.out.println("概率"+ran1);
    			// 产生方式
    			for (i = 0; i < scale; i++) {
    				if (ran1 <= Pi[i]) {
    					break;
    				}
    			}
    			selectId = i;
    			copyGh(k, selectId);
    		}
    	}
     
    	public void evolution() {
    		int k;
    		// 挑选某代种群中适应度最高的个体
    		selectBestGh();
    		// 赌轮选择策略挑选scale-1个下一代个体
    		select();
    		float r;
     
    		// 交叉方法
    		for (k = 0; k < scale; k = k + 2) {
    			r = random.nextFloat();// /产生概率
    			// System.out.println("交叉率..." + r);
    			if (r < Pc) {
    				// System.out.println(k + "与" + k + 1 + "进行交叉...");
    				OXCross(k, k + 1);// 进行交叉
    			} else {
    				r = random.nextFloat();// /产生概率
    				// System.out.println("变异率1..." + r);
    				// 变异
    				if (r < Pm) {
    					// System.out.println(k + "变异...");
    					OnCVariation(k);
    				}
    				r = random.nextFloat();// /产生概率
    				// System.out.println("变异率2..." + r);
    				// 变异
    				if (r < Pm) {
    					// System.out.println(k + 1 + "变异...");
    					OnCVariation(k + 1);
    				}
    			}
     
    		}
     
    	}
    	
     
    	// 两点交叉算子
    	void OXCross(int k1, int k2) {
    		int i, j, flag;
    		int ran1, ran2, temp = 0;
     
    		ran1 = random.nextInt(65535) % LL;
    		ran2 = random.nextInt(65535) % LL;
     
    		while (ran1 == ran2) {
    			ran2 = random.nextInt(65535) % LL;
    		}
    		if (ran1 > ran2)// 确保ran1<ran2
    		{
    			temp = ran1;
    			ran1 = ran2;
    			ran2 = temp;
    		}
    		flag = ran2 - ran1 + 1;// 个数
    		for (i = 0, j = ran1; i < flag; i++, j++) {
    			temp = newPopulation[k1][j];
    			newPopulation[k1][j] = newPopulation[k2][j];
    			newPopulation[k2][j] = temp;
    		}
     
    	}
     
    	// 多次对换变异算子
    	public void OnCVariation(int k) {
    		int ran1, ran2, temp;
    		int count;// 对换次数
    		count = random.nextInt(65535) % LL;
     
    		for (int i = 0; i < count; i++) {
     
    			ran1 = random.nextInt(65535) % LL;
    			ran2 = random.nextInt(65535) % LL;
    			while (ran1 == ran2) {
    				ran2 = random.nextInt(65535) % LL;
    			}
    			temp = newPopulation[k][ran1];
    			newPopulation[k][ran1] = newPopulation[k][ran2];
    			newPopulation[k][ran2] = temp;
    		}
    	}
    
  • 运行截图:

  • psp流程:
    任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min)
    计划 70 40
    查阅相关资料 30 20
    规划PSP流程 40 20
    开发 480 300
    编写算法 180 120
    具体设计 120
    代码复审 180 180
    报告 130 110
    编写博客 90 90
    上传代码 10
    总结流程 30 20
  • 小结感受:两人合作真的能够带来1+1>2的效果吗?

    • 一方面,两人合作可以互相交流看法,并且减少工作量,能够在合作过程中互相发现并弥补自身不足,有利于更好的学习;
    • 另一方面,将各自分工结合起来会出现各种问题,并且在各自思想上会有局限性。
posted @ 2021-04-14 09:52  对他使用炎拳吧  阅读(77)  评论(0编辑  收藏  举报