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的效果。首先,在软件开发的过程中,结对编程可以提高软件开发效率的;其次,它还可以减少软件中的错误与漏洞。另外,在测试过程中,我和结对伙伴可以分饰两角:软件工程师和客户,可以更好的去改进项目,提高软件项目的人机交互体验。但是,由于我们编程能力都不好,所以,任务完成得不是很好。
  • 相关阅读:
    linux网络编程-socket(36)
    linux网络编程-socket(2)
    linux网络编程-socket(1)
    jni不通过线程c回调java的函数
    jni 字符串的梳理 2 字符串的处理操作
    jni 字符串的梳理
    android studio 中jni底层日志的打印
    事件冒泡与事件捕获
    盒子模型
    比较好的前端面试题
  • 原文地址:https://www.cnblogs.com/chanyeol1127/p/14651945.html
Copyright © 2011-2022 走看看