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的真切感受,希望在以后的学习中加强合作。
- 结对编程中需要加强交流与合作,大胆的提出意见,相互监督
- 要多多注意结对方的特点善于利用自身优势