xiaojiuguan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

201871010133-赵永军 实验二 D{0-1}背包问题项目报告

项目 内容
课程班级博客链接 18计师班
这个作业要求链接 作业要求
我的课程学习目标 1、掌握软件项目个人开发流程;
2、掌握Github发布软件项目的操作方法。
这个作业在哪些方面帮助我实现学习目标 1、总结《构建之法》第1章、第2章,掌握PSP流程;
2、开发个人项目,并掌握背包问题。
项目Github的仓库链接地址 Github地址

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

博客发布人 链接
周学铭 点评链接
郑文潇 点评链接
魏娜娜 点评链接

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

第1章

1.1 软件=程序+软件工程

  • 程序=数据结构+算法
  • 简单的应用程序--->满足这种功能的应用软件--->保证服务质量的软件服务
  • 软件工程的要求质量保证、用户体验、国际化和本地化
  • 软件工程的工作有源代码管理、配置管理、软件项目的管理、需求分析、软件测试、程序理解、软件维护/服务维护
  • 软件企业 = 软件 + 商业模式
  • 软件开发的不同阶段
    • 玩具阶段
    • 业余爱好阶段
    • 探索阶段
  • 商业软件vs爱好者写的程序

1.2软件工程是什么

软件工程是把系统的、有序的、可量化的方法应用到软件的开发、运营和维护上的过程。
软件工程包括下列领域: 软件需求分析、软件设计、软件构建、软件测试和软件维护。
软件工程和下列的学科相关: 计算机科学、计算机工程、管理学、数学、项目管理学、质量管理、软件人体工学、系统工程、工业设计和用户界面设计。

1.2.1 软件的特殊性
  • 复杂性
  • 不可见性
  • 易变性
  • 服从性
  • 非连续性
1.2.2 软件工程与计算机科学的关系
  • 计算机科学中偏理论的领域,大多与数学、离散数学、数理逻辑密切相关。
  • 计算机科学中偏实践的领域,大多和数据以及其他学科发生关系。
  • 软件工程和人的行为、现实社会的需求息息相关。
1.2.3 软件工程的目标——创造“足够好”的软件
  • 用户满意度
  • 可靠性
  • 软件流程的质量
  • 可维护性

第2章

    软件是由多人合作完成的,不同人员的工作相互有依赖关系。例如,一个人写的模块被其他人写得模块调用。软件的很多错误都来源于程序员对模块功能的误解、疏忽或不了解模块的变化。如何能让自己负责的模块功能定义尽量明确,模块内部的改变不会影响其他模块,而且模块的质量能得到稳定的、量化的保证?单元测试就是一个很有效的解决方法。

2.1单元测试

2.1.1 用VSTS写单元测试
2.1.2 好的单元测试的标准
  • 单元测试应该在最基本的功能/参数上验证程序的正确性。
  • 单元测试必须由最熟悉代码的人(程序的作者)来写。
  • 单元测试过后,机器状态保持不变。
  • 单元测试要快(一个测试的运行时间是几秒钟,而不是几分钟)。
  • 单元测试应该产生可重复、一致的结果。
  • 独立性——单元测试的运行/通过/失败不依赖于别的测试,可以人为构造数据,以保持单元测试的独立性。
  • 单元测试应该覆盖所有代码路径。
  • 单元测试应该集成到自动测试的框架中。
  • 单元测试必须和产品代码一起保存和维护。
2.1.3 回归测试
  • 针对一个Bug Fix,我们也要做Regression Test。目的是:
             1.验证新的代码的确改正了缺陷
             2.同时要验证新的代码有没有破坏模块现有的功能,有没有Regression

2.2效能分析工具

  • 两种分析方法:
    1.抽样
    2.代码注入

2.3个人开发流程

PSP2.1
Planning 计划
· Estimate *估计这个任务需要多少时间
Development 开发
· Analysis *分析需求
· Design Spec *生成设计文档
· Design Review *设计复审(和同事审核设计文档)
· Coding Standard *代码规范(为目前的开发制定合适的规范)
· Design *具体设计
· Coding *具体编码
· Code Review *代码复审
· Test *测试(包括自测,修改代码,提交修改)
Record Time Spent 记录用时
Test Report 测试报告
Size Measurement 计算工作量
Postmortem 事后总结
Process Improvement Plan 提出过程改进计划

2.4实践

2.4.1 基本作业:从Hello World开始
2.4.2 实践最简单的项目:WC
  • 实现一个简单而完整的软件工具(源程序特征统计程序)
  • 进行单元测试、回归测试、效能测试,在实现上述程序的过程中使用相关的工具
  • 进行个人软件过程(PSP)的实践,逐步记录自己在每个软件工程环节花费的时间。
  • 使用项目管理系统,练习使用其中的事件跟踪系统。(选用TFS,Bugzilla或者Trac,了解原理)
2.4.2.1 WC项目要求
  • 程序处理用户需求的模式为:
             wc.exe[parament][file_name]
  • 各个参数的意义:
  • 基本功能列表:
             wc.exe-c file.c:        char count
             wc.exe-w file.c:       word count
             wc.exe-l file.c:                   line count
2.4.2.2 工作的细分
  • 罗马不是一天建成的。三个估计时间。
2.4.2.3 如何保证质量——回归测试
  • 手动测试,手工比较。
  • 要做到不断地测试,可以把WC的主要功能封装成一个类,然后测试程序调用这个类的主要函数,得出结果并与标准做比较。
  • 更进一步,把测试文件和正确的测试结果保存在文件中,测试驱动程序只要比较测试的输出和标准结果就能得出答案。
  • 再进一步,把自动构建脚本和构建验证测试结合起来。每一次构建之后,就自动运行测试,然后记录出现的Bug。
2.4.2.4 标准测试集,正确性和速度评比
  • 记录实际时间和时间分配。

任务3:个人项目开发

3.1需求分析

  • 本次题目主要是通过动态规划算法和回溯算法来求解指定D{0-1} KP数据的最优解和求解时间(以秒为单位),而0/1背包问题对于物品的选择只有两种:装入或者不装入背包。那么如何选择装入背包的物品,使得包中物品的总价值最大?我将使用动态规划算法分以下三步来实现:
    • 确定动态规划函数:根据子问题之间的重叠关系找到子问题满足的递推关系式(即动态规划函数),这是动态规划算法的关键。
    • 实现对于已有数据集的.txt文件的读取以及对于字符流的处理,使它能够变成我们所能够使用的数据。

3.2功能设计

  • 读取文件数据:可正确读入实验数据文件的有效D{0-1}KP数据;
  • 绘制散点图:绘制任意一组D{0-1}KP数据以重量为横轴、价值为纵轴的数据散点图;
  • 排序:对一组D{0-1}KP数据按项集第三项的价值:重量比进行非递增排序;
  • 求解最优解和时间:求解指定D{0-1} KP数据的最优解和求解时间(以秒为单位);
  • 将数据结果保存为txt文件:将一组D{0-1} KP数据的最优解、求解时间和解向量保存为txt文件;

3.3设计实现

  • 本次实验设计主要针对5个功能的实现来设计的
    • 第一个模块是正确读入数据,用python按行读取;
    • 第二个模块则是利用python的matplotlib库中scatter函数轻松实现;
    • 第三个模块先是使用dict(zip(list1,list2))生成字典实现价值重量比和物品的对于关系;
    • 第四个模块是用动态规划算法;
    • 第五个模块是将结果保存在txt文件中。

3.4测试运行

1.读取相应的文件,选择文件中的数据进行图表的绘制

2.在读取的数据中选择某一项数进行按照重量比进行非递增排序


3.分别对于一组数据进行回溯算法和动态规划算法进行计算最优解,并将其结果保存至文件中


3.5代码片段

  • 读入数据
def getData():
    # -------打开指定文件,读入数据-------
    fileName = str(input('请输入文件名'))
    file = open(fileName, 'r')
    line = file.readline()
    while (line):
        # 读入一行数据
        line = file.readline()
        # 如果匹配到profit关键字,则读入下一行的价值信息
        if line.__contains__("profit"):
            # 去除结尾的换行符,逗号,原点,便于分割
            line = file.readline().strip('\n').strip('.').strip(',')
            # 将该行数据存入列表
            profitData.append(line)
        # 如果匹配到weight关键字,则读入下一行的重量信息
        elif line.__contains__("weight"):
            # 去除结尾的换行符,逗号,原点,便于分割
            line = file.readline().strip('\n').strip('.').strip(',')
            # 将该行数据存入列表
            weightData.append(line)
  • 项集第三项的价值:重量比的非递增排序代码如下:
Ratio = []     #项集所有项比值
Ratio_1 = []    #第三项比值排序
n = len(x)
for i in range(n):    #将项集的所有项比值存入Ratio
    ratio = y[i]/x[i]
    Ratio.append(ratio)
for i in range(2, len(Ratio), 3):    #将第三项的比值存入Ratio_1
    ratio_1 = Ratio[i]
    Ratio_1.append(ratio_1)
Ratio_1.sort(reverse=True)   #排序
print('排序结果为:',Ratio_1)
  • 绘制散点图
#导入必要的模块   
import numpy as np  
import matplotlib.pyplot as plt
del W[-1]
del V[-1]
x = list(map(int, W))   #将字符型转换为整形
y = list(map(int, V))
plt.scatter(x, y)   #画散点图
plt.show()
  • 动态规划算法
def pack(w, v, n, c):
	dp = [0 for _ in range(c+1)]
	for i in range(1, len(w)+1):
	    for j in reversed(range(1, c+1)):
	        for k in range(3):
	            if j-w[i-1][k] >= 0:
	                # print(dp[j])
	                dp[j] = max(dp[j], dp[j-w[i-1][k]] + v[i-1][k])
	    # print(dp)
	print(dp[c])
  • 保存数据到txt文件
if __name__ == '__main__':
    fw = open("result.txt", 'w')  # 将要输出保存的文件地址
    for line in open("result.txt"):  # 读取的文件
        fw.write(result)
        fw.write("\n")  # 换行
  • 菜单函数
def menu():
    print("1.绘制散点图")
    print("2.排序")
    print("3.算法实现")
    print("4.退出")
    task = raw_input("请输入选项进行对应操作")

    if task == '1':
        user_dict = creating_dictionary()

    elif task == '2':
        updating_dictionary(user_dict)

    elif task == '3':
        sorting_dictionary(user_dict)
    elif task == '4':
        break

3.6总结

  • 本次实验我的“模块化”实际上还是一个大程序,一是因为使用Python相比其他语言来说代码少,对于完成本次实验的调试影响不大;二是在实验前我花了大量的时间去分析设计实验;三是由于没有很好的利用好PSP,时间安排出现紧张而最后的时间里仍然坚持自己完成,为节约时间便没有设计独立模块,而是根据自己分析的结果使用大程序里的“模块化”来完成实验,这是我未来要改正的错误,值得总结出来并反思。

3.7通过阅读了解到了个人项目在实施的过程中,PSP的思想及重要性,下面表格为展示的 本次个人项目中的PSP项目规划表格。

PSP 各个阶段 自己预估的时间(分钟) 实际的记录(分钟)
计划: 明确需求和其他因素,估计以下的各个任务需要多少时间 2*60 3*60
开发 (包括下面 8 项子任务) 37*60 41*60
· 需求分析 (包括学习新技术、新工具的时间) 3*60 3*60
· 生成设计文档 (整体框架的设计,各模块的接口,用时序图,快速原型等方法) 2*60 2*60
· 设计复审 (和同事审核设计文档,或者自己复审) 1*60 1*60
· 代码规范 (为目前的开发制定或选择合适的规范) 1*60 1*60
· 具体设计(用伪代码,流程图等方法来设计具体模块) 3*60 4*60
· 具体编码 25*60 25*60
· 代码复审 1*60 2*60
· 测试(自我测试,修改代码,提交修改) 1*60 3*60
报告 1*60 2*60
测试报告 1*60 2*60
计算工作量 (多少行代码,多少次签入,多少测试用例,其他工作量) 1*60 2*60
事后总结, 并提出改进计划 (包括写文档、博客的时间) 2*60 3*60
总共花费的时间 (分钟) 44*60 53*60
  • 本次设计的PSP各个阶段是以小时为单位来估计的,可能存在误差,并且没有记录这些阶段是哪天完成的,导致自己在项目初期没有认真去做,到最后时间才完成了项目,所以我认为在项目开始应该把PSP中各个阶段的具体时间写进去。
  • 通过计划与实际的时间来对比,我发现我的编程能力还有待提高,导致我在编码过程中不仅慢,而且还出现了很多问题,导致计划时间与实际时间不相符。

任务4:本次项目提交Github

Github链接

  • 截图
posted on 2021-03-31 13:02  赵永军  阅读(231)  评论(2编辑  收藏  举报