201971010121-李健康 实验二 个人项目—《01背包问题》项目报告
项目 | 内容 |
---|---|
课程班级博客 | https://edu.cnblogs.com/campus/xbsf/2019nwnucs |
作业要求 | https://edu.cnblogs.com/campus/xbsf/2019nwnucs/homework/12527 |
课程学习目标 | (1)掌握软件项目个人开发流程;(2)掌握Github发布软件项目的操作方法 |
项目Github的仓库 | https://github.com/yingyaoyao/01- |
实验内容
任务1 阅读教师博客“常用源代码管理工具与开发工具”,并评论至少3位同学的博客
梁春云 | 评论地址 |
---|---|
毕之xk | 评论地址 |
bkbkb | 评论地址 |
任务2 总结详细阅读《构建之法》第1章、第2章,掌握PSP流程
1.第一章主要讲述了:
(1)软件的定义:
软件=程序+软件工程 程序=数据结构+算法
(2)软件工程的定义:
软件工程是把系统的、有序的、可量化的方法应用到软件开发、运营和维护上的过程;
软件的特殊性:1.复杂性;2.不可见性;3.易变性;4.服从性;5.非连续性;
软件工程的目标:创造“足够好”的软件;
2.第二章主要讲述了:
(1)如何对软件进行单元测试:
1.单元测试应该在最基本的功能/参数上验证程序的正确性;2.单元测试必须由最熟悉代码的人(程序的作者)来写;3.单元测试过后,机器状态保持不变;4.单元测试要快(一个测试的运行时间是几秒钟,而不是几分钟);5.单元测试应该产生可重复、一致的结果;6.独立性—————单元测试的运行/通过/失败不依赖于别的测试,可以人为构造数据,以保持单元测试的独立性;7.单元测试应该覆盖所有代码路径;8.单元测试应该集成到自动测试的框架中;9.单元测试必须和产品代码一起保存和维护;
(2)个人开发流程(PSP)
1.特点:
* 不局限于某一种软件技术(如编程语言),而是着眼于软件开发的流程,这样,开发不同应用的软件工程师可以互相比较。
* 不依赖于考试,而主要靠工程师自己收集数据,然后分析,提高。
* 在小型、初创的团队中,很难找到高质量的项目需求,这意味着给程序员的输人质量不高。在这种情况下,程序员的输出(程序/软件)往往质量也不高,然而这并不能全部由程序员负责。
* PSP 依赖于数据。
* PSP 的目的是记录工程师如何实现需求的效率,而不是记录顾客对产品的满意度。
任务3 项目开发
1.项目背景
背包问题(Knapsack Problem,KP)是NP Complete问题,也是一个经典的组合优化问题,有着广泛而重要的应用背景。{0-1}背包问题({0-1 }Knapsack Problem,{0-1}KP)是最基本的KP问题形式,它的一般描述为:从若干具有价值系数与重量系数的物品(或项)中,选择若干个装入一个具有载重限制的背包,如何选择才能使装入物品的重量系数之和在不超过背包载重前提下价值系数之和达到最大?
2.需求分析
{0-1}KP数据集是研究{0-1}背包问题时,用于评测和观察设计算法性能的标准数据集;动态规划算法、回溯算法是求解{0-1}背包问题的经典算法。查阅相关资料,设计一个采用贪心算法、动态规划算法、回溯算法求解{0-1}背包问题的程序
(1)贪心算法求解{0-1}背包问题。即局部最优解;
(2)动态规划算法求解{0-1}背包问题。每次遍历到的第 i 个物品,根据 weight[i] 与 value[i] 来确定是否需要将该物品放入背包中。即对于给定的 n个物品,设 weight[i]、value[i] 分别为第 i 个物品的重量与价值,m 为背包的容量。再令 v[i][j] 表示在前 i 个物品中进行组合后装入容量为 j 的背包中的最大价值。
(3)回溯算法求解{0-1}背包问题。01背包属于找最优解问题,用回溯法需要构造解的子集树。对于每一个物品i,对于该物品只有选与不选2个决策,总共有n个物品,可以顺序依次考虑每个物品,这样就形成了一棵解空间树: 基本思想就是遍历这棵树,以枚举所有情况,最后进行判断,如果重量不超过背包容量,且价值最大的话,该方案就是最后的答案。
3.功能设计
(1)可正确读入实验数据文件的有效{0-1}KP数据;
(2)能够绘制任意一组{0-1}KP数据以价值重量为横轴、价值为纵轴的数据散点图;
(3)能够对一组{0-1}KP数据按重量比进行非递增排序;
(4)用户能够自主选择贪心算法、动态规划算法、回溯算法求解指定{0-1} KP数据的最优解和求解时间(以秒为单位);
(5)任意一组{0-1} KP数据的最优解、求解时间和解向量可保存为txt文件或导出EXCEL文件。
4.设计实现
(1)动态规划算法:void Knap1();void Buildx() //回推求最优解;
(2)贪心算法:void Knap2() //求解背包问题并返回总价值;
(3)回溯算法:void Backtrack();
(4)void disp_bestx() //输出结果;
(5)代码片段
1.动态规划算法
点击查看代码
void Knap1()
{
int i, r;
for (i = 0; i <= n; i++) //置边界条件dp[i][0] = 0
dp[i][0] = 0;
for (r = 0; r <= W; r++) //置边界条件dp[0][r] = 0
dp[0][r] = 0;
for (i = 1; i <= n; i++) {
for (r = 1; r <= W; r++) {
if (r < w[i])
dp[i][r] = dp[i - 1][r];
else
dp[i][r] = max(dp[i - 1][r], dp[i - 1][r - w[i]] + v[i]);
}
}
}
void Buildx() //回推求最优解
{
int i = n, r = W;
bestp = 0;
while (i >= 0) {
if (dp[i][r] != dp[i - 1][r]) {
x[i] = 1;
bestp += v[i];
r = r - w[i];
}
else
x[i] = 0;
i--;
}
}
点击查看代码
void Knap2() //求解背包问题并返回总价值
{
maxv = 0; //maxv初始化为0
int weight = W; //背包中能装入的余下重量
memset(x, 0, sizeof(x)); //初始化x向量
int i = 1;
while (A[i].w <= weight) //物品i能够全部装入背包时,循环
{
x[i] = 1; //装入物品i
weight -= A[i].w; //减少背包中能装入的余下重量
maxv += A[i].v; //计算装入物品i后的总价值
i++;
}
}
void disp_bestx() {
int sumw = 0;
cout << "放入购物车的物品序号为:";
for (int j = 1; j <= n; j++) {
if (x[j] == 1) {
cout << j << " ";
sumw += A[j].w;
}
}
cout << endl;
cout << "放入购物车的物品最大价值为:" << maxv << ",总重量为:" << sumw << endl;
}
点击查看代码
void Backtrack(int t, int tw, int tv, int op[])
{
if (t > n) { //找到一个叶子结点
if (tw <= W && tv > bestp) { //找到一个满足条件的更优解,保存它
bestp = tv;
for (int j = 1; j <= n; j++)
x[j] = op[j];
}
}
else { //还没搜寻玩所有物品
if (tw + w[t] <= W) { //左孩子结点剪枝:满足条件才放入第i个物品
op[t] = 1; //选取第i个物品
Backtrack(t+1,tw+w[t],tv+v[t],op);
}
op[t] = 0; //不选取第i个物品,回溯
Backtrack(t + 1, tw, tv, op);
}
}
void disp_bestx() {
int i;
int sumw = 0;
cout << "放入购物车的物品序号为:";
for (i = 1; i <= n; i++) {
if (x[i] == 1) {
cout << i << " ";
sumw += w[i];
}
}
cout << endl;
cout << "放入购物车的物品最大价值为:" << bestp << ",总重量为:" << W << endl;
}
4.结果截图
以beibao0数据为例:
1.读取数据
2.输出结果
5.PSP展示
PSP2.1 | 任务内容 | 计划共完成需要的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
Planning | 计划 | 5 | 7 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 5 | 7 |
Development | 开发 | 241 | 328 |
Analysis | 需求分析(包括学习新技术) | 12 | 15 |
Design Spec | 生成设计文档 | 14 | 19 |
Design Review | 设计复审(和同事审核设计文档) | 15 | 20 |
Coding Standard | 代码规范(为目前的开发制定合适的规范) | 10 | 15 |
Design | 具体设计 | 90 | 125 |
Coding | 具体编码 | 40 | 60 |
Code Review | 代码复审 | 30 | 40 |
Test | 测试(自我测试,修改代码, 提交修改) | 30 | 34 |
Reporting | 报告 | 48 | 68 |
Test Report | 测试报告 | 20 | 24 |
Size Measurement | 计算工作量 | 16 | 24 |
Postmortem & Process Improvement Plan | 事后总结,并提出过程改进计划 | 12 | 20 |
6.经验分享
{0-1}背包问题是一个在算法领域内比较经典的问题,我是在上学期的《算法设计与分析》这门课程中第一次了解到的。由于有上学期的学习基础,所以在本次程序设计中没有太多的大问题。另一方面,在本次项目结束后,我发现自己对程序设计这一方面有了更多的认识和理解,从最开始懵懂到想在的初步设计,是我对软件工程这门课程产生了极大的兴趣,希望在接下来的项目中能够体会其中的奥义所在。