201971010145-姚恪 实验三 结对项目—《{0-1}KP 实例数据集算法实验平台》项目报告

项目 内容
课程班级博客 19卓越
作业要求链接 实验三
我的课程学习目标 (1)体验软件项目开发中的两人合作,练习结对编程(Pair programming)
(2)掌握Github协作开发软件的操作方法
这个作业在哪些方面帮助我实现学习目标 (1) 阅读课外资料,理解并掌握代码风格规范、代码设计规范、代码复审、结对编程概念
(2)体验结对编程,相互提高 (3)合作开发D{0-1}KP 实例数据集算法实验平台,并实现遗传算法
结对方学号-姓名 201971010208-古丽
结对方本次博客作业链接 对方博文
本项目Github的仓库链接地址 仓库

一、阅读《现代软件工程—构建之法》第3-4章内容
1.代码风格规范

  • 缩进:可以使用Tab键以及2、4、8等空格。个人认为依据不同是编程语言,可以使用不同的缩进方式。
  • 行宽:对行宽进行同一设置。
  • 括号:用括号清楚的表明逻辑优先级。
  • 分行:不要把多条语句放在一行上。
  • 命名:命名能够表明变量的类型及相应的语义,简洁易懂。
  • 下换线:合理使用来分隔变量名字中的作用域标注和变量的语义。
  • 大小写:多个单次组成的变量名,用大小写区分,例如著名的驼峰式命名法。
  • 注释:能够很好的解释程序是做什么的,以及为什么这样做。

2.代码设计规范

  • c++类的处理:注意类、classvc.struct、公共/保护/私有成员、数据成员、虚函数、构造函数、析构函数、new和delete、运算符、异常处理、类型继承等的规范设计。
  • 错误处理:预留足够的时间,使用的方法包括参数处理和断言。
  • 断言:使用断言来验证正确性。
  • 参数处理:在debug版本中,所有的参数都要验证其正确性。在正式版本中,对从外部(用户或别的模块)传递过来的参数,要验证其正确性。
  • 构造函数:不要在构造函数中做复杂的操作,简单初始化所有数据成员即可。构造函数不应该返回错误(事实上也无法返回)。把可能出错的操作放到HrInit()或FInit()中。
  • 数据成员:数据类型的成员用m_ name说明。不要使用公共的数据成员,要用inline访问函数,这样可兼顾封装和效率。

3.代码复审

  • 自我复审
  • 同伴复审
  • 团队复审

4.结对编程

  • 两人结对编程,一对程序员肩并肩,平等地,互补地进行开发工作。

二、对结对方《实验二 软件工程个人项目》的项目成果进行评价

项目 内容
结对方学号-姓名 201971010208-古丽
结对方作业二博客 作业博客
结对方作业二仓库地址 仓库地址

(1)评论对方博客

  • 博文结构:
    • 整体博客十分简洁,但是内容齐全,排版规矩。
  • 博文内容:
    • 总体上完成了要求的内容,但对于项目描述的详细程度有所不足,在“模块化”等方面也有一定欠缺。
  • 博文结构与PSP中“任务内容”列的关系:
    • 博文结构与“内容任务”列并非完全对应。博文结构主要应用“从面至点”的思路,由整体开发思路到详细编码内容。
  • PSP中“计划共完成需要的时间”与“实际完成需要的时间”两列数据的差异化分析与原因探究:
    • 实际完成需要的时间比计划共完成需要的时间更长,作者提到其自身编码能力有所不足,导致了实际时间的增加

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

  • 克隆对方仓库代码

  • 测试代码

  • 代码核查表
项目 内容
概要部分
代码符合需求和规格说明么? 代码符合需求
代码设计是否考虑周全? 考虑周全
代码可读性如何? 能够顺利阅读
代码容易维护么? 不容易维护
代码的每一行都执行并检查过了吗? 检查了
设计规范部分
设计是否遵从已知的设计模式或项目中常用的模式? 是的
代码有没有依赖于某一平台,是否会影响将来的移植(如Win32到Win64)? 没有
开发者新写的代码能否用已有的Library/SDK/Framework中的功能实现?在本项目中是否存在类似的功能可以调用而不用全部重新实现? 可以用;存在,有些代码是可以调用的
有没有无用的代码可以清除?
代码规范部分
修改的部分符合代码标准和风格么? 修改的部分不符合代码标准和风格。
具体代码部分
有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常? 进行了处理没有异常
参数传递有无错误,字符串的长度是字节的长度还是字符(可能是单/双字节)的长度,是以0开始计数还是以1开始计数? 无错误;本项目中是以0开始计数。
边界条件是如何处理的?switch语句的default分支是如何处理的?循环有没有可能出现死循环? 没有死循环
有没有使用断言(Assert)来保证我们认为不变的条件真的得到满足?
对资源的利用是在哪里申请,在哪里释放的?有没有可能导致资源泄露(内存、文件、各种GUI资源、数据库访问的连接,等等)?有没有优化的空间? 在内存申请会泄露
数据结构中有没有用不到的元素?
效能
代码的效能(Performance)如何?最坏的情况如何? 效能正常
代码中,特别是循环中是否有明显可优化的部分
对于系统和网络调用是否会超时?如何处理? 没有超时
可读性
代码可读性如何?有没有足够的注释? 分段处有注释
可测试性
代码是否需要更新或创建新的单元测试?针对特定领域的开发(如数据库、网页、多线程等),可以整理专门的核查表。 可以继续开发加强功能

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

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

(1)需求分析

  • 平台基础功能:实验二 任务3;
  • {0-1}KP 实例数据集需存储在数据库;
  • 平台可动态嵌入任何一个有效的{0-1}KP 实例求解算法,并保存算法实验日志数据;
  • 人机交互界面要求为GUI界面(WEB页面、APP页面都可);
  • 查阅资料,设计遗传算法求解{0-1}KP,并利用此算法测试要求(3);
  • 附加功能:除(1)-(5)外的任意有效平台功能实现。

(2)软件设计说明

  • 将实验二的代码进行了扩充,套装了一个django框架
  • 但是仅仅能够实现数据的前端展示,是一个假的前端,没有完全实现前端功能
  • 使用python中django库中自带的sqlite数据库进行数据的传输
  • 功能流程图
graph LR start[算法平台] --> input[选择一个指定的背包数据] input --> conditionA[显示背包数据] conditionA --> conditionB[遗传算法] conditionA --> conditionC[动态规划] conditionA --> conditionD[贪心算法] conditionA --> conditionE[回溯法] conditionB --> printa[散点图] conditionC --> printa[散点图] conditionD --> printa[散点图] conditionE --> printa[散点图] printa --> stop[结束]

(3)核心代码展示

  • 遗传算法
    遗传算法通常实现方式为一种计算机模拟。对于一个最优化问题,一定数量的候选解(称为个体)可抽象表示为染色体,使种群向更好的解进化。传统上,解用二进制表示(即0和1的串),但也可以用其他表示方法。进化从完全随机个体的种群开始,之后一代一代发生。在每一代中评价整个种群的适应度,从当前种群中随机地选择多个个体(基于它们的适应度),通过自然选择和突变产生新的生命种群,该种群在算法的下一次迭代中成为当前种群。
  ##初始化,N为种群规模,n为染色体长度
  def init(self,N,n):
      C = []
      for i in range(N):
          c = []
          for j in range(n):
              a = np.random.randint(0,2)
              c.append(a)
          C.append(c)
      return C


  ##评估函数
  # x(i)取值为1表示被选中,取值为0表示未被选中
  # w(i)表示各个分量的重量,v(i)表示各个分量的价值,w表示最大承受重量
  def fitness(self,C,N,n,W,V,w):
      S = []##用于存储被选中的下标
      F = []## 用于存放当前该个体的最大价值
      for i in range(N):
          s = []
          h = 0  # 重量
          f = 0  # 价值
          for j in range(n):
              if C[i][j]==1:
                  if h+W[j]<=w:
                      h=h+W[j]
                      f = f+V[j]
                      s.append(j)
          S.append(s)
          F.append(f)
      return S,F

  ## 适应值函数,B位返回的种族的基因下标,y为返回的最大值
  def best_x(self,F,S,N):
      y = 0
      x = 0
      B = [0]*N
      for i in range(N):
          if y<F[i]:
              x = i
          y = F[x]
          B = S[x]
      return B,y

  ## 计算比率
  def rate(self,x):
      p = [0] * len(x)
      s = 0
      for i in x:
          s += i
      for i in range(len(x)):
          p[i] = x[i] / s
      return p

  ## 选择
  def chose(self,p, X, m, n):
      X1 = X
      r = np.random.rand(m)
      for i in range(m):
          k = 0
          for j in range(n):
              k = k + p[j]
              if r[i] <= k:
                  X1[i] = X[j]
                  break
      return X1

  ## 交配
  def match(self,X, m, n, p):
      r = np.random.rand(m)
      k = [0] * m
      for i in range(m):
          if r[i] < p:
              k[i] = 1
      u = v = 0
      k[0] = k[0] = 0
      for i in range(m):
          if k[i]:
              if k[u] == 0:
                  u = i
              elif k[v] == 0:
                  v = i
          if k[u] and k[v]:
              # print(u,v)
              q = np.random.randint(n - 1)
              # print(q)
              for i in range(q + 1, n):
                  X[u][i], X[v][i] = X[v][i], X[u][i]
              k[u] = 0
              k[v] = 0
      return X

  ## 变异
  def vari(self,X, m, n, p):
      for i in range(m):
         for j in range(n):
              q = np.random.rand()
              if q < p:
                  X[i][j] = np.random.randint(0,2)
  	return X
  • 使用diango框架和构造数据库
def main():
    """Run administrative tasks."""
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ex3.settings')
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == '__main__':
    main()
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

(4)程序运行截图

  • 数据排序进行选择
  • 操作之后的记录

(5)结对过程

(6)本次作业PSP

PSP 任务内容 计划需要的时间 (min) 实际完成需要的时间 (min)
Planning 计划 30 30
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 30 30
Development 开发 1000 1000+
Analysis 需求分析 (包括学习新技术) 120 150
Design Spec 生成设计文档 20 15
Design Review 设计复审 (和同事审核设计文档) 20 15
Coding Standard 代码规范 (为目前的开发制定合适的规范) 20 15
Design 具体设计 50 60
Coding 具体编码 600 650
Code Review 代码复审 20 40
Test 测试(自我测试,修改代码,提交修改) 200 220
reporting 报告 100 110
testreport 测试报告 40 30
Size Measurement 计算工作量 50 55
Postmortem & Process Improvement Plan 事后总结 ,并提出过程改进计划 20 30

(7)小结感受

  • 通过本次结对项目,感受到了1+1>2的真切感受,希望在以后的学习中加强合作。
  • 结对编程中需要加强交流与合作,大胆的提出意见,相互监督
  • 要多多注意结对方的特点善于利用自身优势
posted @ 2022-04-04 13:56  星空云朵  阅读(86)  评论(2编辑  收藏  举报