zoukankan      html  css  js  c++  java
  • 201871010014-陈园园 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容
    课程班级博客链接 班级博客
    这个作业要求链接 作业要求
    我的课程学习目标 (1)体验并感受两人合作,结对编程完成软件项目的开发。(2)练习Github协作开发程序的操作方法和过程。
    这个作业在哪些方面帮助我实现学习目标 (1)学习效率方面。两人合作结对编程的方式,提高了学习效率。(2)学习能力方面。一个人可能会学的很快,但两人人合作会使学习能力加强。(3)学习经验方面。相互学习可以取长补短,积累知识,增加学习经验。(4)学习内容方面。双方讨论学习可以深入探讨知识,学习内容更加充实。
    结对方学号-姓名 201871010105—曹玉中
    结对方本次博客作业链接 结对方博客作业链接
    本项目Github的仓库链接地址 仓库链接

    博客正文

    任务1:

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

    第3章基本内容:

      (1) 个人能力的衡量与发展:软件工程包括了开发、运用、维护软件的过程中的很多技术、做法、习惯和思想。软件工程把这些相关的技术和过程统一到一个体系中,叫“软件开发流程”,软件开发流程的目的是为了提高软件开发、运营和维护的效率,以及提升用户满意度、软件的可靠性和可维护性。
      (2)初级软件工程师的成长包括以下几种:
       a.积累软件开发相关的知识,提升技术技能(如对具体技术的掌握,动手能力)。例如:对JAVA、C/C++、C#的掌握,诊断/提高效能的技术,对于某一开发平台的掌握等。
       b.积累问题领域的知识和经验。
       c.对通用的软件设计思想和软件工程思想的理解。
       d.提升职业技能,包括:自我管理的能力、表达交流的能力、与人合作的能力等。
       e.实际成果——最重要的评价标准。
     (3)软件工程师的职业发展:[软件工程师自我评价能力表](https://www.cnblogs.com/xinz/p/3852177.html)
    

    第4章基本内容:

    名词 内容
    代码风格规范 主要是文字上的规定。(1)代码风格的原则是:简明、易读、无二义性;(2)对于缩进、行宽、括号、分行、命名、下划线、注释、大小写以及断行与空白的{}行的处理;(3)缩进限定为100字符;(4)复杂的条件表达式中,用括号表示逻辑优先级;(5)有清晰的断行和分行;命名应该遵循规则,简洁易懂。
    代码设计规范 (1)牵扯到程序设计、模块之间的关系、设计模式等。(2)针对函数:只做一件事,并且要做好。可以使用goto实现单一的出口;(3)还有错误处理方面的一些内容,比如断言的正确使用等规范;(4)错误处理的时间更甚于程序功能的实现;(5)所有的参数都要验证其正确性,验证正确性使用断言。
    代码复审 (1)形式:自我复审、同伴复审、团队复审;(2)目的:找出代码错误、发现逻辑错误、发现算法错误、发现潜在的错误和回归性错误、发现可能需要改进的地方、传授经验;(3)代码复审后把记录整理出来:更正明显的错误、记录无法很快更正的错误、把所有的错误记在自己的一个“我常犯的错误”表中,作为以后自我复审的第一步。
    结对编程概念 角色:驾驶员:控制键盘输入;领航员:起到领航、提醒的作用。好处:(1)在开发层次,可以提供更好的设计质量和代码质量,两人合作解决问题的能力更强。(2)对开发人员,带来更多的信心,高质量的产出带来更高的满足感。(3)企业管理层次上,有效地交流,相互学习和传递经验,分享知识,取得更高的投入产出比。

    任务2:

    两两自由结对,对结对方《实验二 软件工程个人项目》的项目成果进行评价,具体要求如下:
    (1)对项目博文作业进行阅读并进行评论,评论要点包括:博文结构、博文内容、博文结构与PSP中“任务内容”列的关系、PSP中“计划共完成需要的时间”与“实际完成需要的时间”两列数据的差异化分析与原因探究,将以上评论内容发布到博客评论区。

    (2)克隆结对方项目源码到本地机器,阅读并测试运行代码,参照《现代软件工程—构建之法》4.4.3节核查表复审同伴项目代码并记录。

    概要部分

     - 代码能符合需求和规格说明么?答:能符合需求与规格。
     - 代码设计是否有周全的考虑? 答:不太周全,修改了很多次,刚开始可能设计部分有一些问题。
     - 代码可读性如何? 答:简单易懂。
     - 代码容易维护么? 答:比较容易。
     - 代码的每一行都执行并检查过了吗? 答:是的,检查过。
    

    设计规范部分

     - 设计是否遵从已知的设计模式或项目中常用的模式? 答:是。
     - 代码有没有依赖于某一平台,是否会影响将来的移植(如Win32到Win64) 答:没有依赖,不会影响。
     - 开发者新写的代码能否用已有的Library/SDK/Framework中的功能实现?在本项目中是否存在类似的功能可以调用而不用全部重新实现? 答:可以实现,不存在。
     - 有没有无用的代码可以清除?(很多人想保留尽可能多的代码,因为以后可能会用上,这样导致程序文件中有很多注释掉的代码,这些代码都可以删除,因为源代码控制已经保存了原来的老代码。) 答:有,已清除。 
    

    代码规范部分

     - 修改的部分符合代码标准和风格么(详细条文略)? 答:符合代码标准。
    

    具体代码部分

     - 有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常? 答:查阅资料并讨论以后发现基本没有。
     - 参数传递有无错误,字符串的长度是字节的长度还是字符(可能是单/双字节)的长度,是以0开始计数还是以1开始计数? 答:基本无错误,字符串的长度是字节的长度,以0开始计数。
     - 边界条件是如何处理的?Switch语句的Default是如何处理的?循环有没有可能出现死循环? 答:通过检查代码和讨论,循环不会出现死循环。
     -有没有使用断言(Assert)来保证我们认为不变的条件真的满足? 答:没有使用。
     - 对资源的利用,是在哪里申请,在哪里释放的?有没有可能导致资源泄露(内存、文件、各种GUI资源、数据库访问的连接,等等)?有没有可能优化? 答:因为没有上线使用,基本不会导致资源泄露,没有优化。
     - 数据结构中是否有无用的元素? 答:检查过后没有。
    

    (3)依据复审结果尝试利用github的Fork、Clone、Push、Pull request、Merge pull request等操作对同伴个人项目仓库的源码进行合作修改。

    任务3:

    采用两人结对编程方式,设计开发一款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)外的任意有效平台功能实现。
    

    设计前期知识:

    遗传算法:
    • 遗传算法是根据生物进化的模型提出的一管优化算法。
    • 原理:遗传算法将生物进化原理引入待优化参数形成的编码串群体中,按着一定的适值函数及一系列遗传操作对各个体进行筛选,从而使适值高的个体被保留下来,组成新的群体,新群体包含上一代的大量信息,并且引入了新的优于上一代的个体。这样周而复始,群体中各个体适值不断提高,直至满足一定的极限条件。此时,群体中适值最高的个体即为待优化参数的最优解。
    • 特点:
      (1)遗传算法是对参数的编码进行操作,而非对参数本身。
      (2)遗传算法是从许多点开始并行操作,并非局限于一点,从而可有效防止搜索过程收敛于局部最优解。
      (3)遗传算法通过目标函数计算适值,并不需要其它推导和附加信息,因而对问题的依赖性较小。
      (4)遗传算法的寻优规则是由概率决定的,而非确定性的。
      (5)遗传算法在解空间进行高效启发式搜索,而非盲目地穷举或完全随机搜索。
      (6)遗传算法对所求解的优化问题没有太多的数学要求。
      (7)遗传算法具有并行计算的特点,因而可通过大规模并行计算来提高计算速度。
    • 基本操作:遗传、变异和交叉。
    • 1、需求分析:遗传算法作为当今一个比较热门的研究方向,在解决最优化问题上有着良好的作用。遗传算法利用基因编码,对其进行生成、杂交、变异、选择等操作,产生不同的基因序列,使解一步一步向最优解逼近,未来发展前景也是相当不错的。
    • 2、设计实现:
      代码片段:
     /*
        初始化种群
         */
        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);
            }
            caculteFitness();
    
    
        }
     /*
        计算种群适应度
         */
        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;
    
    
        }
     /*
        进化算法
         */
        public void evolve() {
            List<Chromosome> childrenGenome = new ArrayList<Chromosome>();
    
            for (int j = 0; j < popSize / 2; j++) {
                Chromosome g1 = getChromoRoulette();
                Chromosome g2 = getChromoRoulette();
                double r = random.nextDouble();
    
                if (r <= crossoverRate) {
                    List<Chromosome> children = genetic(g1, g2);
                    if (children != null) {
                        for (Chromosome g : children) {
                            changeGene(g);
                            childrenGenome.add(g);
                            g.mutation(50, mutationRate);
                            changeGene(g);
                            childrenGenome.add(g);
                        }
                    }
    
                }
                childrenGenome.add(g1);
                childrenGenome.add(g2);
            }
            List<Chromosome> temGen = new ArrayList<Chromosome>();
            population.clear();
    
            for (int i = 0; i < popSize*0.2; i++) {
                int max = 0;
    
                for (Chromosome tempG : childrenGenome) {
                    if (tempG.getFitness() > max) {
                        max = tempG.getFitness();
                        setBestFit(tempG);
                    }
    
                }
                temGen.add(getBestFit());
                childrenGenome.remove(getBestFit());
                setBestFit(null);
    
            }
            population = childrenGenome;
            caculteFitness();
    
            while (temGen.size() < popSize) {
                Chromosome tp1 = getChromoRoulette();
                temGen.add(tp1);
            }
    
            /*
            while (temGen.size()<popSize){
                Chromosome tp1=new Chromosome(50);
                temGen.add(tp1);
            }
            */
    
            population = temGen;
    
    
            //重新计算种群适应度
            caculteFitness();
        }
        /*
        遗传算法GA流程
         */
        public void geneticAlgorithProcess(){
            generation=1;
            init();
            while(generation<iterNum){
                evolve();
                print();
                generation++;
            }
        }
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		System.out.println("doGet is called========");
    		response.setContentType("text/html");
    		PrintWriter out = response.getWriter();//获得输出流对象
    		String name=request.getParameter("username");
    		String pass=request.getParameter("password");
    		if(name.equals("xyz")&&pass.equals("123")){
    			out.println(" login success!");//用输出流,向客户端输出响应
    			System.out.println("login success!");//服务器端控制台输出
    		}
    		else{
    			out.println(" login failed!");//用输出流,向客户端输出响应
    			System.out.println("login failed!");//服务器端控制台输出
    		}
    	}
    
    • 3、程序运行:

    • 4、结对的过程:

    • 5、结对编程PSP:

    任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min)
    计划 40 30-40
    · 估计这个任务需要多少时间,并规划大致工作步骤 25 20-30
    开发 900 1000
    需求分析 (包括学习新技术) 30-40 35
    · 生成设计文档 25 30
    · 设计复审 (和同事审核设计文档) 120 130
    代码规范 (为目前的开发制定合适的规范) 100 100
    具体设计 200-300 150
    具体编码 680-800 900
    · 代码复审 100 110
    · 测试(自我测试,修改代码,提交修改) 70 90
    报告 80 60
    · 测试报告 30 30
    计算工作量 40 30-50
    · 测试报告 25 10-20
    · 事后总结 ,并提出过程改进计划 15 15
    • 7、小结感受
      通过这次实验的结对编程,我觉得两人合作真的能够带来1+1>2的效果。首先,在软件开发的过程中,结对编程可以提高软件开发效率的;其次,它还可以减少软件中的错误与漏洞。另外,在测试过程中,我和结对伙伴可以分饰两角:软件工程师和客户,可以更好的去改进项目,提高软件项目的人机交互体验。但是,由于我们编程能力都不好,所以,任务完成得不是很好。
  • 相关阅读:
    LeetCode 189. Rotate Array
    LeetCode 965. Univalued Binary Tree
    LeetCode 111. Minimum Depth of Binary Tree
    LeetCode 104. Maximum Depth of Binary Tree
    Windows下MySQL的安装与配置
    LeetCode 58. Length of Last Word
    LeetCode 41. First Missing Positive
    LeetCode 283. Move Zeroes
    《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践》读后感
    删除docker下的镜像
  • 原文地址:https://www.cnblogs.com/chanyeol1127/p/14651945.html
Copyright © 2011-2022 走看看