201971010150-闫雨馨 实验二 软件个人项目——{0-1}背包问题
项目 | 内容 |
---|---|
课程班级博客 | 2019级计算机科学与技术 |
作业要求 | 实验二 软件工程个人项目 |
我的课程学习目标 | 掌握软件项目个人开发流程 掌握Github发布软件项目的操作方法 掌握常用源代码管理工具与开发工具 |
这个作业在哪些方面帮助我实现学习目标 | 通过对{0-1}背包问题这个软件项目的开发,掌握软件项目个人开发流程 将项目源码的完整工程文件提交到Github账号的项目仓库中,掌握Github发布软件项目的操作方法 |
- 任务一完成情况说明:
- 阅读[教师博客],了解了常用源代码管理工具与开发工具(HTTPS://WWW.CNBLOGS.COM/NWNU-DAIZH/P/14521534.HTML)
- 点评三篇班级博客
- 任务二完成情况说明:
- 总结详细阅读《构建之法》第1章、第2章,掌握PSP流程
1.第一章:主要详细讲解了什么是软件工程:
- 软件 = 程序 + 软件工程:
邹欣老师首先解释了什么是“软件”,什么是“程序”,为我们介绍了软件工程的概念。最后讲述了软件开发的不同阶段,引出了什么是软件工程这个问题。 - 软件工程的定义:
软件工程的特殊性:复杂性,不可见性,易变性,服从性,非连续性;
软件工程的知识领域、软件工程的三大类基础知识领域:计算基础,数学基础和工程基础;
软件工程的目标:用户满意度,可靠性,软件流程的质量,可维护性。
2.第二章:主要讲解了PSP(个人软件开发流程):
- PSP特点:
- 不局限于某一种软件技术,而是着眼于软件开发的流程
- 不依赖于考试,而是依赖工程师自己收集数据,然后分析,提高
- 依赖于数据
- PSP作用:
PSP可以帮助软件工程师在个人的基础上运用过程的原则,借助于PSP提供的一些度量和分析工具,了解自己的技能水平,控制和管理自己的工作方式,使自己日常工作的评估、计划和预测更加准确、更加有效,进而改进个人的工作表现,提高个人的工作质量和产量,积极而有效地参与高级管理人员和过程人员推动的组织范围的软件工程过程改进。
3.展示PSP:
PSP2.1 | 任务内容 | 计划共完成需要的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
Planning | 计划 | 12 | 10 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 12 | 10 |
Development | 开发 | 759 | 893 |
Analysis | 需求分析 (包括学习新技术) | 35 | 56 |
Design Spec | 生成设计文档 | 20 | 45 |
Design Review | 设计复审 (和同事审核设计文档) | 60 | 90 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 5 | 8 |
Design | 具体设计 | 70 | 100 |
Coding | 具体编码 | 500 | 850 |
Code Review | 代码复审 | 120 | 150 |
Test | 测试(自我测试,修改代码,提交修改) | 150 | 200 |
Reporting | 报告 | 80 | 80 |
Test Report | 测试报告 | 30 | 30 |
Size Measurement | 计算工作量 | 25 | 30 |
Postmortem & Process Improvement Plan | 事后总结 ,并提出过程改进计划 | 45 | 50 |
-
任务三完成情况说明:
-
项目开发背景
背包问题(Knapsack Problem,KP)是NP Complete问题,也是一个经典的组合优化问题,有着广泛而重要的应用背景。{0-1}背包问题({0-1 }Knapsack Problem,{0-1}KP)是最基本的KP问题形式,它的一般描述为:从若干具有价值系数与重量系数的物品(或项)中,选择若干个装入一个具有载重限制的背包,如何选择才能使装入物品的重量系数之和在不超过背包载重前提下价值系数之和达到最大? -
项目要求
- 可正确读入实验数据文件的有效{0-1}KP数据
- 能够绘制任意一组{0-1}KP数据以价值重量为横轴、价值为纵轴的数据散点图
- 能够对一组{0-1}KP数据按重量比进行非递增排序
- 用户能够自主选择贪心算法、动态规划算法、回溯算法求解指定{0-1} KP数据的最优解和求解时间(以秒为单位)
- 任意一组{0-1} KP数据的最优解、求解时间和解向量可保存为txt文件或导出EXCEL文件
-
项目流程
- 排序:使用快速排序对程序中的数据进行排序
- 散点图绘制:使用 Python 中的 Matplotlib库 来进行绘制
- 算法:
- 贪心算法:按单位重量价值从小到大排序,依次装入性价比最高的物品
- 动态规划法:求出状态转移方式,分阶段一步步求解
- 回溯法:构造解的子集树,遍历这棵树,枚举所有情况,进行判断
-
代码规范
项目 | 规则 |
---|---|
缩进 | 使用 tab 作为缩进 |
变量命名 | (1)均不能以下划线开始,也不能以下划线结束; (2)禁止英文与拼音混用,仅允许纯拼音或纯英文; (3)采用类驼峰形式,命名首字母可小写,如 getMaxWeight 或 WriteFile; (4)允许单个小写英文字母的命名; (5)允许纯大写英文字母的命名 |
每行最多字符数 | 单行字符数限制不超过256个 |
函数最大行数 | 单个函数行数限制不超过120行 |
函数、类命名 | (1)均不能以下划线开始,也不能以下划线结束; (2)禁止英文与拼音混用,仅允许纯拼音或纯英文; (3)采用类驼峰形式,命名首字母可小写,如 getMaxWeight 或 WriteFile; (4)允许纯大写英文字母的命名 |
常量 | 同变量命名规则 |
空行规则 | (1)引入头文件其间部分不允许空行; (2)静态变量/常量定义后跟一空行; (3)每个函数后跟一空行,除非是最后一个函数; (4)若函数为空,中间包含一空行; (5)其余除为了代码美观的空行,均不允许空行出现 |
注释规则 | (1)行内注释可使用//...形式; (2)函数前部注释需使用/*内容/形式 |
操作符前后空格 | (1)if/for/while/switch/do等保留字与左右括号之间都必须加空格; (2)其余运算符左右均不加空格 |
其他规则 | (1)左大括号前不换行; (2)右大括号前换行 |
- 核心代码
- 贪心法:
def fractional_backpack(goods, w):
m = [0 for _ in range(len(goods))]
total_v = 0
for i, (prize, weight) in enumerate(goods):
if w >= weight:
m[i] = 1
total_v += prize
w -= weight
else:
m[i] = w / weight
total_v += m[i] * prize
w = 0
break
return total_v, m
- 动态规划法:
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(v, w, c, n, x, i):
global bestV, currV, currW
if i >= n:
if bestV < currV:
bestV = currV
else:
if currW + w[i] <= c:
x[i] = 1
currW += w[i]
currV += v[i]
backtrack(v, w, c, n, x, i + 1)
currW -= w[i]
currV -= v[i]
x[i] = 0
backtrack(v, w, c, n, x, i + 1)
- 散点图绘制
- 总结
在这次实验中我学习了PSP流程,并且运用PSP流程去严格执行里面的流程实现软件项目,我觉得这是一次全新的体验,更加了解到了学习软件工程这门课的重要性,也知道了一个项目开发的计划和预估有多重要。PSP如果做好了会让人更加明确整个项目的流程和具体思路,PSP也让我学会了更加规范的去进行软件开发。其次,在这次实验中还学习到了用python画散点图,以及用python将数据的最优解、求解时间和解向量保存为txt文件。但是,在有限的时间内没有实现更加完整的实现项目需要达到的功能。希望在今后的学习过程中能继续努力,继续进步。 - 任务四完成情况说明:
完成任务3的程序开发,将项目源码的完整工程文件提交到Github账号的项目仓库中