项目 内容
课程班级博客链接 班级博客
这个作业要求链接 作业要求
我的课程学习目标 运用科学高效的方法学习软件工程的理论和知识
这个作业在哪些方面帮助我实现学习目标 掌握软件项目个人开发流程,掌握Github发布软件项目的操作方法
项目Github的仓库链接地址 Github仓库地址

1、实验目的与要求

(1)掌握软件项目个人开发流程。
(2)掌握Github发布软件项目的操作方法。

2、实验内容

  • 任务1:阅读教师博客“常用源代码管理工具与开发工具”内容要求,点评班级博客中已提交相关至少3份作业。

  • 任务2:详细阅读《构建之法》第1章、第2章,掌握PSP流程

  • 卡内基梅隆大学(CMU)的能力熟度模型(CMM和CMMI),这是用来衡量团队能力的一套模型。 CMU 的专家们针对软件工程师也有一套模型: 叫 Personal Software Process (PSP)

    • PSP 和任何其他方法论一样, 也不是一蹴而就的。下图显示了CMU Personal Software Process 的各个版本的内容 (来源: CMU PSP 网站)。红字标出了每个版本新增的内容:

    • 我们用最新的版本 (PSP 2.1) 来看看一个软件工程师在接到一个任务之后应该怎么做:

  • PSP  的特点:
    •       不局限于某一种软件技术 (如编程语言),  而是着眼于软件开发的流程,  这样不同应用的工程师可以互相比较。
    •       不依赖于考试, 而主要靠工程师自己收集数据, 然后统计提高。
    •       在小型,初创的团队中,  高质量的项目需求很难找到,这意味着给程序员的输入质量不高,在这种情况下,  程序员的输出 (程序/软件) 往往质量不高, 然而这并不能全部由程序员负责。
    •       PSP 依赖于数据
    •       PSP的目的是记录工程师如何实现需求的效率,  而不是记录顾客对产品的满意度。

  • 任务3:采用动态规划算法、回溯算法求解D{0-1}背包问题

  • 项目开发背景:

    • 背包问题(Knapsack Problem,KP)是NP Complete问题,也是一个经典的组合优化问题,有着广泛而重要的应用背景。{0-1}背包问题({0-1 }Knapsack Problem,{0-1}KP)是最基本的KP问题形式,它的一般描述为:从若干具有价值系数与重量系数的物品(或项)中,选择若干个装入一个具有载重限制的背包,如何选择才能使装入物品的重量系数之和在不超过背包载重前提下价值系数之和达到最大? D{0-1} KP 是经典{ 0-1}背包问题的一个拓展形式,用以对实际商业活动中折扣销售、捆绑销售等现象进行最优化求解,达到获利最大化。D{0-1}KP数据集由一组项集组成,每个项集有3项物品可供背包装入选择,其中第三项价值是前两项之和,第三项的重量小于其他两项之和,算法求解过程中,如果选择了某个项集,则需要确定选择项集的哪个物品,每个项集的三个项中至多有一个可以被选择装入背包,D{0-1} KP问题要求计算在不超过背包载重量 的条件下,从给定的一组项集中选择满足要求装入背包的项,使得装入背包所有项的价值系数之和达到最大;D{0-1}KP instances数据集是研究D{0-1}背包问题时,用于评测和观察设计算法性能的标准数据集;动态规划算法、回溯算法是求解D{0-1}背包问题的经典算法。
    • 查阅相关资料,设计一个采用动态规划算法、回溯算法求解D{0-1}背包问题的程序,程序基本功能要求如下:
        1.可正确读入实验数据文件的有效D{0-1}KP数据;
        2.能够绘制任意一组D{0-1}KP数据以重量为横轴、价值为纵轴的数据散点图;
        3. 能够对一组D{0-1}KP数据按项集第三项的价值:重量比进行非递增排序;
        4.用户能够自主选择动态规划算法、回溯算法求解指定D{0-1} KP数据的最优解和求解时间(以秒为单位);
        5.任意一组D{0-1} KP数据的最优解、求解时间和解向量可保存为txt文件或导出EXCEL文件。
  • 需求分析:
      采用动态规划算法、回溯算法求解D{0-1}背包问题的程序。正确读入实验数据文件的有效D{0-1}KP数据;能够绘制任意一组D{0-1}KP数据以重量为横轴、价值为纵轴的数据散点图; 能够对一组D{0-1}KP数据按项集第三项的价值:重量比进行非递增排序;用户能够自主选择动态规划算法、回溯算法求解指定D{0-1} KP数据的最优解和求解时间(以秒为单位);任意一组D{0-1} KP数据的最优解、求解时间和解向量可保存为txt文件或导出EXCEL文件。

  • 功能设计:
      输入输出文件;能够绘制任意一组D{0-1}KP数据以重量为横轴、价值为纵轴的数据散点图; 对一组D{0-1}KP数据按项集第三项的价值:重量比进行非递增排序;用户能够自主选择动态规划算法、回溯算法求解指定D{0-1} KP数据的最优解和求解时间(以秒为单位)。

  • 设计实现:
      针对任务三运用动态规划算法、回溯算法求解指定D{0-1} KP数据的最优解和求解时间(以秒为单位),主要设计函数有动态规划求解,回溯法求解,以及输出最优解;动态规划,对每一件物品遍历背包容量,当背包可容纳值大于等于当前物品,与之前已放进去的物品所得价值进行对比,考虑是否需要置换;用回溯法求解需要构造解的子集树。对于每一个物品i,对于该物品只有选与不选2个决策,总共有n个物品,可以顺序依次考虑每个物品,这样就形成了一棵解空间树:基本思想就是遍历这棵树,以枚举所有情况,最后进行判断,如果重量不超过背包容量,且价值最大的话,该方案就是最后的答案。在搜索状态空间树时,只要左子节点是可一个可行结点,搜索就进入其左子树。对于右子树时,先计算上界函数,以判断是否将其减去(剪枝)。

  • 测试运行:

  • 代码片段:

文件打开与数据预处理:
file=open('D:\Course\软件工程\实验二 任务3data_set\idkp1-10.txt','r')
file1=open('D:\Course\软件工程\实验二 任务3data_set\i.txt','w')
string=file.read().strip()
ss=string.split('\n')
s=[]
for i in ss:
    i.rstrip(',')
    i.rstrip('\n')
    i.rstrip('.')
    if i.startswith('*') or i.startswith('The') or i.startswith('IDK') or i==''  :
        continue
    else:
        s.append(i[:-1])
print(s)
file1.write("\n".join(s))
file.close()
file1.close()
散点图绘制:
fig,ax=plt.subplots()
ax1=plt.subplot(1,1,1)
for i in range(0,len(s)-1,2):
    x=list(map(int,s[i].split(',')))
    y=list(map(int,s[i+1].split(',')))
    ax1.scatter(x,y)
    plt.show()
动态规划:
def bag(n,c,w,v):
	res=[[-1 for j in range(c+1)] for i in range(n+1)]
	for j in range(c+1):
		res[0][j]=0
	for i in range(1,n+1):
		for j in range(1,c+1):
			res[i][j]=res[i-1][j]
			if j>=w[i-1] and res[i][j]<res[i-1][j-w[i-1]]+v[i-1]:
				res[i][j]=res[i-1][j-w[i-1]]+v[i-1]
	return res
回溯法:
def backtrack(i):
	global bestV,curW,curV,x,bestx
	if i>=n:
		if bestV<curV:
			bestV=curV
			bestx=x[:]
	else:
		if curW+w[i]<=c:
			x[i]=True
			curW+=w[i]
			curV+=v[i]
			backtrack(i+1)
			curW-=w[i]
			curV-=v[i]
		x[i]=False
		backtrack(i+1)
  • 提交项目源码到Github
  • 总结:软件设计的“模块化”原则
      软件设计的模块化可以解决软件的复杂性问题,或者说降低软件的复杂性,模块化是以分治法为基础,简单说就是把软件整体划分,划分后的块组成了软件,这些块都相互独立,每个块完成一个功能,多个块组合可以完成一系列功能。
    一、提高工作效率
      比如在项目A中写一个模块,A完工后启动了项目B,在B中就可以直接复用项目A的模块了,一个可复用的软件可以为将来节省费用,被复用的频率越高,组件的开发成本就越低。
    二、提高软件质量
      可复用的软件比不能复用的有更多的质量保障,因为可复用的软件在不断的复用过程中可以排除一些bug和缺陷,因此可复用的软件有利于系统的可维护性。
  • PSP展示:
PSP2.1 任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min)
lanning 计划 10 20
· Estimate · 估计这个任务需要多少时间,并规划大致工作步骤 10 20
Development 开发 330 520
· Analysis · 需求分析 (包括学习新技术) 30 30
· Design Spec · 生成设计文档 30 30
· Design Review · 设计复审 (和同事审核设计文档) 30 30
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30 30
· Design · 具体设计 30 50
· Coding · 具体编码 120 220
· Code Review · 代码复审 30 50
· Test · 测试(自我测试,修改代码,提交修改) 30 80
Reporting 报告 40 60
· Test Report · 测试报告 15 20
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结 ,并提出过程改进计划 15 30
  通过分析自己的估计和实际消耗时间,发现我在具体设计环节耗时最多,需求分析和具体设计阶段的实际用时比预期长了许多,主要是因为需求分析阶段需要完成查阅资料等工作,比较花费时间,而具体编码阶段需要复习一部分以前学过的算法等内容,并且还要学习项目中需要用到的以前未掌握的知识和技术。
  • 任务4:完成个人项目报告博文作业

3、实验总结

  本次实验主要是通过完成个人项目的过程中,学会软件项目个人开发流程,掌握Github发布软件项目的操作方法。对于此次的项目设计,我有很多地方还很不完善。一开始拿到题目时,我打算选择C++语言开发,因为学习算法时基本是以C++实现的,但是实验任务中又需要绘制散点图以及处理数据,由于我对java的掌握很薄弱,最后我选择了python,上学期学过一些数据分析与可视化的内容,对于此次题目要求的一部分(绘制任意一组D{0-1}KP数据以重量为横轴、价值为纵轴的数据散点图)比较符合。但是做的时候又出了各种问题,花费了不少时间;读入txt后对数据的处理等,因此,在psp中的需求分析和具体设计阶段的实际用时比预期长了许多,以及具体设计和编码的时间也超出预期很多。希望能借此次教训,在以后的项目开发中能够实打实的考虑好项目需求,尽量避免做无用功。除此之外,在需求分析中,我的预期和实践相差较大,对数据的处理这块的知识有了好多模糊的地方,不得不查阅一些资料、视频来学习。在这次的开发中,我更加体会到用进行实际项目开发的不易。总之,本次实验不仅让我学会软件项目个人开发流程,掌握Github发布软件项目的操作方法,而且使我深刻认识到自己在解决问题时的不足,在以后的学习中要多花时间,更加努力。