201971010106-陈玉英 实验三 结对项目—《{0-1}KP 实例数据集算法实验平台》项目报告

项目 内容
课程班级博客链接 2019级卓越工程师班
这个作业链接 实验三 软件工程结对项目
我的课程学习目标 (1) 掌握软件项目个人开发流程,掌握Github发布软件项目的操作方法;(2)加深了解D{0-1}KP问题;(3)了解并熟悉遗传算法;(4)在结对合作过程中获得除知识外其他能力。
这个作业在哪些方面帮助我实现学习目标 (1)通过软件项目合作开发,体会到了结对编程的真正益处;(2)通过对不了解的知识内容进行学习,提升自己的编程能力的同时也对自我学习的要求有高层次要求。
结对方学号-姓名 201971010157-张颖
结对方本次博客作业链接 201971010157-张颖 实验三 结对项目—《{0-1}KP 实例数据集算法实验平台》项目报告
本项目Github的仓库链接地址 Github的仓库
  • 任务一:阅读《现代软件工程—构建之法》第3-4章内容,理解并掌握代码风格规范、代码设计规范、代码复审、结对编程概念
  1. 代码风格规范:代码风格并不会影响程序的运行,但一段好的代码风格,能让人阅读起来特别舒服。在企业合作中代码格式规范是十分重要的。

  2. 代码设计规范:代码设计规范可以分为架构设计、类的设计、函数的设计、Log的设计以及竞态关系的设计(多线程的设计)等等,通过这些设计,可以使代码更加规范,标准。

  3. 代码复审:代码审查是任何正式开发过程中的必要环节。但大多数开发者不知道的是,代码审查分为很多种类型。根据你项目和团队架构的不同,每一种代码审查类型都有它特有的优缺点。我们可以在一个很高的层面可以将代码审查归为两大类:正式的代码审查(formal code review)和轻量级的代码审查(light weight code review)。

      * 正式的代码审查:正式的代码审查是基于正式的开发流程。其中最流行的实践是范根检查法(Fagan inspection)。它为试图寻找代码的缺陷提供了一种非常结构化的流程,并且,它还可以用于发现规范(specifications)中的或者设计中的缺陷。范根检查法由6个步骤组成:计划(Planning),概述(Overview),准备(Preparation),召开检查会议(Inspection Meeting),重做(Rework),和追查(Follow-up)。基本的思想是:预先制定好每一个步骤所需要达到的输出要求。接下来,当进行到某个过程时,你检查其现在的输出,并与之前制定的理想输出要求做比较。然后,你由此来决定,是否进入下一个步骤,或者仍需在当前步骤继续工作。
      * 轻量级的代码审查:如今,轻量级的代码审查在开发团队中很常用。可以将轻量级的代码审查细分为如下不同的子类
    

    代码复审的正确定义:看代码是否在“代码规范”的框架内正确地解决了问题

    名称 形式 目的
    自我复审 自己 vs. 自己 用同伴复审的标准来要求自己。不一定最有效,因为开发者对自己总是过于自信。如果能持之以恒,则对个人有很大好处
    同伴复审 复审者 vs. 开发者 简便易行
    团队复审 团队 vs. 开发者 有比较严格的规定和流程,用于关键的代码,以及复审后不再更新的代码。 覆盖率高——有很多双眼睛盯着程序。但是有可能效率不高(全体人员都要到会)
  4. 结对编程:结对编程(英语:Pair programming)是一种敏捷软件开发的方法,两个程序员在一个计算机上共同工作。一个人输入代码,而另一个人审查他输入的每一行代码。输入代码的人称作驾驶员,审查代码的人称作观察员(或导航员)。两个程序员经常互换角色。在结对编程中,观察员同时考虑工作的战略性方向,提出改进的意见,或将来可能出现的问题以便处理。这样使得驾驶者可以集中全部注意力在完成当前任务的“战术”方面。观察员当作安全网和指南。结对编程对开发程序有很多好处。比如增加纪律性,写出更好的代码等。

  5. 代码风格规范包含缩进、行宽、括号、断行与空白的{}行、分行、命名、下划线、大小写、注释。

     * 缩进:如何缩进,缩进几个空格?这些是需要统一的,一般用Tab键缩进4个空格。
     * 行宽:行宽必须限制,但是以前有些文档规定的80字符行宽太小了,现在时代不同了,可以限定为100字符。
     * 括号:在复杂的条件表达式中,用括号清楚地表示逻辑优先级。
     * 程序的风格:最简格式、断行结构、用“{“和”}”来判断程序的结构,改进的结构、“{”和“}”独占一行结构
     * 分行:不要把多条语句放在一行上,更严格地说,不要把多个变量定义在一行上,
     * 命名:变量命名一般要符合的规则是“看名知意”,也就是说看到这个变量的命名,就可以知道这个变量名是做什么的。
     * 下划线:下划线用来分隔变量名字中的作用域标注和变量的语义,如:一个类型的成员变量通常用"m"表示,或者简单地用一个下划线“_”来做前缀。移山公司规定下划线一般不用在其他方面。
    
  6. 代码设计规范(不同的编程语言具有不同的设计规范,但是也有通用的原则。)

     * 函数:现代程序设计语言中的绝大部分功能,都在程序的函数( Function、Method )中实现。关于函数,最重要的原则是:只做一件事,并且要做好。
     * goto:函数最好有单一的出口,为了达到这一目的,可以使用goto。只要有助于程序逻辑的清晰体现,什么方法都可以使用,包括 goto。
     * 错误处理:当程序的主要功能实现后,一些程序员会乐观地估计只需要另外20%的时间,给代码加一些错误处理就大功告成了,但是这20%的工作往往需要全部项目80%的时间。
     * 参数处理
     * 断言
    
  7. 两人合作的不同阶段和技巧:

     * 萌芽期间(Forming):这一阶段由于两人刚认识,有不同的期望值,彼此双方并不了解,需要更多的磨合。
     * 磨合阶段(Storing):刚开始合作时,总会出现这样那样的情况,但是只有这样才会加深彼此之间的认识。
     * 规范阶段(Norming):在经过了磨合阶段后,成员之间主键合拍,许多意见和建议取得一致,并且配合紧密。
     * 创造阶段(Performing):在经过上述三个阶段后,团队成员之间可以达到合二为一的效果,但是并不是所有的合作都能达到这一阶段,磨合太多后,可能进入“解体阶段”。
     * 解体阶段(Deforming):由于在“磨合阶段”一方无法接受另一方,导致失败,只能散伙或找其他合作伙伴。
                          在两人合作期间,因为每个人都是一个独立的个体,都有各自的意见和想法,那么在两个人平等合作的情况下,如何影响对方,如何说服对方。
    
  • 任务2:两两自由结对,对结对方《实验二 软件工程个人项目》的项目成果进行评价
    (1)对项目博文作业进行阅读并进行评论:
    我的评论:

    (2)克隆结对方项目源码到本地机器,阅读并测试运行代码

    项目 内容
    结对方链接 201971010157-张颖 实验二 个人项目-《0-1背包问题》项目报告
    结对方Github项目仓库链接 GIthub项目仓库

    以beibao0数据测试 ,结果如下:


    测试过程发现这个功能存在问题:任意一组{0-1} KP数据的最优解、求解时间和解向量可保存为txt文件或导出EXCEL文件,经过修改已经实现:

    (3)代码核查表:

    复审部分 提出问题 执行情况
    概要部分 1)代码符合需求和规格说明么? 1)代码部分被分成了多个部分,功能较周全;
    2)代码设计是否考虑周全? 2)代码分模块完整
    3)代码可读性如何? 3)可读性较强
    4)代码容易维护么? 易维护
    5)代码的每一行都执行并检查过了吗? 5)是
    设计规范部分 1)设计是否遵从已知的设计模式或项目中常用的模式? 1)设计较为遵从常用模式
    2)有没有硬编码或字符串/数字等存在? 2)有字符串和数字存在
    3)代码有没有依赖于某一平台,是否会影响将来的移植(如Win32到 Win64 ) ? 3)是
    4)开发者新写的代码能否用已有的Library/SDK/Framework中的功能实现?在本项目中是否存在类似的功能可以调用而不用全部重新实现? 4)开发者新写的代码无法用已有的Library/SDK/Framework中的功能实现
    5)有没有无用的代码可以清除? 5)基本没有无用代码
    代码规范部分 修改的部分符合代码标准和风格吗? 修改的部分符合代码标准和风格
    具体代码部分 1)有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常? 1)开发者对错误进行了处理,并且处理错误之后还进行了分析
    2)参数传递有无错误,字符串的长度是字节的长度还是字符(可能是单/双字节)的长度,是以0开始计数还是以1开始计数? 2)字符串的长度是以0开始计数
    3)边界条件是如何处理的?switch语句的default分支是如何处理的?循环有没有可能出现死循环? 缺少跳出循环部分,加入break已解决
    4)有没有使用断言(Assert)来保证我们认为不变的条件真的得到满足?
    5)对资源的利用,是在哪里申请,在哪里释放的?有无可能存在资源泄漏(内存、文件、各种GUI资源、数据库访问的连接,等等)?有没有优化的空间?
    6)数据结构中有没有用不到的元素?
    效能 1)代码的效能( Performance )如何?最坏的情况是怎样的? 代码最坏的情况是运行出错,代码效能较好
    2)代码中,特别是循环中是否有明显可优化的部分(C++中反复创建类,C# 中 string的操作是否能用StringBuilder来优化)?
    3)对于系统和网络的调用是否会超时?如何处理? 2)对于系统和网络的调用可能会超时,因为在运用回溯算法的时候耗时较长
    可读性 代码可读性如何?有没有足够的注释? 可读性较好,有足够的注释
    可测试性 代码是否需要更新或创建新的单元测试? 需要
  • 任务3:采用两人结对编程方式,设计开发一款{0-1}KP 实例数据集算法实验平台
    1.需求分析:目前,修改过的 {0-1}背包问题已经实现了实验二任务3(实验二链接)的基本功能,但当{0-1}KP实例中各项的价值系数与重量系数在大范围内取值时缺乏实用性,为解决这个问题此次项目提出了一种新的求解{0-1}KP的算法,即遗传算法。并且在此基础开发设计开发一款{0-1}KP 实例数据集算法实验平台,来实现人机交互界面。

     * who 为谁设计,用户是谁?
      背包问题(Knapsack Problem,KP)是NP Complete问题,也是一个经典的组合优化问题,有着广泛而重要的应用背景。对于有不同需求的使用者,可以自主选择算法求解问题或者进行不同的项目需求。
     * what 要解决什么问题?
      数据选择:可以选择任意一组数组;
      算法选择:用户能够自主选择贪心算法、动态规划算法、回溯算法、遗传算法求解指定{0-1} KP数据的最优解和求解时间(以秒为单位),并保存算法实验日志数据;
      数据保存:任意一组{0-1} KP数据的最优解、求解时间和解向量可保存为txt文件或导出EXCEL文件;
      散点图绘制:能够绘制任意一组{0-1}KP数据以价值重量为横轴、价值为纵轴的数据散点图;
      排序:能够对一组{0-1}KP数据按重量比进行非递增排序;
      数据库存储:{0-1}KP 实例数据集需存储在数据库;
      对以上功能放入实验平台,人机交互界面要是GUI界面。
    * why 为什么解决这些问题?
      将零散的功能放在一个平台,可以方便使用者体验。
    
    1. 实验平台要求:(平台基础功能:实验二 任务3实验二链接
      (1){0-1}KP 实例数据集需存储在数据库;
      (2)平台可动态嵌入任何一个有效的{0-1}KP 实例求解算法,并保存算法实验日志数据;
      (3)人机交互界面要求为GUI界面(WEB页面、APP页面都可);
      (4)遗传算法求解{0-1}KP,并利用此算法测试要求(2);
      3.{0-1}KP 实例数据集需存储在数据库
      利用MySQL软件与Python数据库连接,将实验二的数据集中的一部分加入数据库,如图所示。

      数据库链接代码:

      4.遗传算法求解{0-1}背包问题:遗传算法可以认为是一种启发式算法,根据达尔文的进化学说中“优胜劣汰”、“适者生存”的观点来解决一些实际生活中难以解决的问题。其实简单来说,遗传算法所做的事情就是“随机”生成一些可行解(不是最优解),然后随机一段时间之后找到局部最优解。但是这个“随机”的过程模拟了自然界中的进化规律,也是“更优解”更容易生存,“更优解”与“更优解”的结合能够生成“更更优解”。不断重复这个结合的过程,最终可以得到局部最优解,甚至可能是全局最优解。
      参考于读懂遗传算法原理如何读懂遗传算法
    种群函数
    交配函数
    交叉函数
    变异函数
    选择函数

    用beibao3数据作为测试:
    算法总结:在测试过程中,我发现事实上遗传算法并没有那么容易实现。就算是对于有唯一解的基础背包问题,也很难保证有正确解。仔细回顾算法的设计其实很容易发现问题的。
    在最开始构造基础population的时候已经不简单了,特别是对于有很多数据的情况,你甚至很难可以随机构造一种情况使得可以满足给定背包重量大小的条件。于是就变成了在一堆不怎么好的sample中,期望通过crossover构造一个较好的sample。这其实是非常不容易的。
    但我其实觉得,这个算法是可行的,但可能需要比较长的时间。我通过增加mutation的概率来使得一些特别的sample能够保留下来,并且能够繁衍。而且我觉得只要进过一段时间后,就可以得到相当不错的结果。
    但是正如前文所说的,遗传算法不是用于求解全局最优解的(虽然如果有全局最优解的话,一般都能够达到),而且用于求解局部最优解的,所以我们可以认为遗传算法得出的结果是“足够好的”,事实上,也确实是如此。

  1. GUI界面设计(利用python自带框架tkinter绘制GUI界面)
    GUI界面设计分为五步:


    实现界面如下:

6.结对PSP展示:

任务内容 计划共完成需要的时间(h) 实际完成需要的时间(h)
计划 1 0.8
估计这个任务需要多少时间,并规划大致工作步骤 1 0.8
开发 34.5 43
需求分析 (包括学习新技术) 3 2
生成设计文档 2 2
生成设计文档 0.5 0.5
代码规范 (为目前的开发制定合适的规范) 1 0.5
具体设计 3 3
具体编码 20 30
代码复审 3 2
测试(自我测试,修改代码,提交修改) 2 3
报告 3 5
测试报告 2 3
计算工作量 0.5 1
事后总结 ,并提出过程改进计划 0.5 1

7.总结:这次项目的完成,我深深体验到了两人合作带来1+1>2的效果,合作最大的好处就是能够取长补短,克服个人能力的不足,一个人的想法有限,两个人的合作,让思维扩展,当一个人的思维受限时,同伴的思维是活跃的,并且可以想到自己想不到的地方。两个人的分工可以让一个项目所花费的时间大大缩短,交流可以让思想融合,可以来说是事半功倍。
其次,这次的项目很多知识是我们不了解的,我们通过查阅资料,相互合作,一点点的啃下来,过程辛苦,结果值得。
8.结对过程记录:


posted @ 2022-04-04 17:13  小福兴  阅读(48)  评论(3编辑  收藏  举报