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


    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('
    ').strip('.').strip(',')
                # 将该行数据存入列表
                profitData.append(line)
            # 如果匹配到weight关键字,则读入下一行的重量信息
            elif line.__contains__("weight"):
                # 去除结尾的换行符,逗号,原点,便于分割
                line = file.readline().strip('
    ').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("
    ")  # 换行
    
    • 菜单函数
    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链接

    • 截图
  • 相关阅读:
    程序员的自我修养---------一个程序员应该懂点什么
    Duilib的圆环形 进度条 实现(网易云信版本)
    位定义,用于判断是否包含某属性
    Duilib的圆角矩形 抗锯齿优化 弥补RoundRect不足(网易云信borderround版本)
    exe、msi、dos、bat等静默运行,后台运行,不弹窗的解决办法
    删除桌面上有文件但提示项目不存在的方法
    MyBatis插入语句返回主键值
    django学习之Model(二)
    TCP三四次握手
    django学习之Model(一)
  • 原文地址:https://www.cnblogs.com/zhaoyongjun0911/p/14567901.html
Copyright © 2020-2023  润新知