201971010242-王凯英 实验二 个人项目—{01背包问题}项目报告

项目 内容
课程班级博客链接 2019级卓越工程师班
这个作业要求链接 软件工程个人项目
我的课程学习目标 (1)掌握软件项目个人开发流程(2)掌握Github发布软件项目的操作方法。
这个作业在哪些方面帮助我实现学习目标 (1)更加熟练git的相关操作;(2)巩固算法设计的思想(3)进一步加深对可视化的认识。
项目Github的仓库链接地址 Github仓库链接

任务一的链接任务一

  • 对以下三位同学的作业进行了评价
姓名 链接
谢雨涵 (https://www.cnblogs.com/201971010247xyh/p/15966838.html#5025832)
张萌 (https://www.cnblogs.com/zm18/p/15954467.html#5025838)
刘转弟 (https://www.cnblogs.com/liuzhuandi/p/15977039.html#5025853)

任务二
第一章:

  • 软件 = 程序 + 软件工程
  • 软件企业 = 软件 + 商业模式
  • 如果把软件开发的不同阶段比作航天事业的发展,好比一个成熟的航空工业中,一个飞机发动机从构思到最后运行,不知道要经历过多少人、多少工序、多少流程、多少相关知识的验证,其中的过程对于常人来说是无法想象的。在软件开发的发展过程中,由最初的个体编程到小团体的编程,到现在一个成熟的团队的工程。
  • 软件工程是把系统的、有序的、可量化的方法应用到软件的开发、运营和维护上的过程。软件工程包括下列领域:软件需求分析、软件设计、软件构建、软件测试和软件维护。软件工程和下列的学科相关:计算机科学、计算机工程、管理学、数学、项目管理学、质量管理、软件人体工学、系统工程、工业设计和用户界面设计。
  • 软件开发过程的五大难题:复杂性、不可见性、易变性、服从性、非连续性。
  • 《构建之法》的教学目标:
  1. 研发出符合用户需求的软件说明
  2. 通过一定的软件流程,在预计的时间内发布“足够好”的软件说明
  3. 并通过数据和其他方式展现所开发的软件是可以维护和继续发展的说明
  4. 能做到以上三点,就是初步学会了软件工程
    第二章:
  • 单元测试
    单元测试的作用:让自己负责的模块功能定义尽量明确,模块内部的改变不会影响其他模块,而且模块的质量能得到稳定的、量化的保证。
    从书中例子可以看出创建单元测试函数的主要步骤是:

  • 设置数据(一个假想的正确的E-mail地址)
    使用被测试类型的功能(用E-mail地址来创建一个User类的实体)
    比较实际结果和预期的结果(Assert.IsTrue(target != null);)

  • 一个好的单元测试应当准确快速的保证程序基本模块的正确性。一个好的单元测试应该满足以下标准:

  1. 单元测试应该在最基本的功能/参数上验证程序的正确性
  2. 单元测试应该由最熟悉代码的人(程序的作者)来写
  3. 单元测试过后机器的状态应保持不变
  4. 单元测试要快
  5. 单元测试应该产生可重复、一致的结果
  6. 独立性-单元测试的运行/通过/失败不依赖别的测试,可以认为构造数据,以保持单元测试的独立性
  7. 单元测试应该覆盖所有代码路径(100%的代码覆盖率不等于100%的正确性)
  8. 单元测试应该集成到自动测试的框架中
  9. 单元测试必须和产品代码一起保存维护
  • PSP特点:
  1. 不局限于某一种软件技术,而是着眼于软件的开发流程
  2. 不依赖考试,而是要靠工程师自己收集数据,然后分析提高依赖于数据
  3. PSP的目的是记录工程师如何完成实现需求的效率,而不是记录顾客对产品的满意度。
  • 总结
    本章主要介绍了PSP,也就是个人软件开发流程,psp就像是一个计划表一样,可以很清晰的看到一个团队的工作流程,还可以通过不同时间的不同的psp进行计较,进而看到团队的提高,一个团队的水平!中间还介绍了一些有关的需要了解掌握的知识,例如单元测试、回归测试、效能分析等,虽然看完了整个章节,但对书中一些调用实例并没有很好的理解,本书是基于C语言的,还需要进行相关的学习!
  • 任务三
  • 需求分析:
    在现实生活中,有一类问题需要设计得出最优解,我们通常使用态规划算法、回溯算法求解D{0-1}背包问题来解决这类问题。背包问题是NP Complete问题,它是一个组合优化问题,而D{0-1} KP 是经典{ 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文件。
  • 总结:你设计的程序如何实现软件设计的“模块化”原则
    模块化设计,顾名思义,一个系统有许多功能,每个功能由不同模块设计实现,通过对各个模块实现连接组成一个系统,修改与添加功能也会方便许多。在本次实验中,需要正确读入实验数据文件的有效{0-1}KP数据。用户可以自主的选择,贪心法,动态规划法,回溯法中的其中一种方法进行实现。所以要至少设置三个模块。
  • psp
PSP2.1 任务内容 计划完成所需要的时间(min) 实际完成所需要的时间(min)
Planning 计划 27 30
Estimate 估计需要的时间并规划步骤 30 27
Development 开发 200 250
Analysis 需求分析 100 110
Design Spec 生成设计文档 20 20
Design Review 设计复审 20 20
Coding Standard 代码规范 10 10
Design 具体设计 10 10
Coding 具体编码 50 60
Code Review 代码复审 60 60
Test 测试 30 20
Reporting 报告 120 110
Test Report 测试报告 30 30
Size Measurement 计算工作量 30 20
Postmortem & Process Improvement Plan 事后总结 ,并提出过程改进计划 40 30
  • 代码片段粘贴
    字符串转换模块代码
/**
     * 字符串数组转int数组
     */
    private static int[] paseStringToInt(String[] splitString) {
        int[] ints = new int[splitString.length];
        for (int i = 0; i < ints.length; i++) {
            ints[i] = Integer.parseInt(splitString[i]);
        }
        return ints;
    }

    /**
     * 字符串分割转存为字符数组
     */
    private static String[] convertStrToArray(String str) {
        String[] strArray = null;
        strArray = str.split(","); //拆分字符为"," ,然后把结果交给数组strArray
        return strArray;
    }

读文件模块代码

/**
     * 读取数据
     */
    public static int readTxtFile(String filePath) {
        try {
            String encoding = "GBK";
            File file = new File(filePath);
            if (file.isFile() && file.exists()) { //判断文件是否存在
                InputStreamReader read = new InputStreamReader(
                        new FileInputStream(file), encoding);//考虑到编码格式
                BufferedReader bufferedReader = new BufferedReader(read);
                String lineTxt = null;
                profitList = new ArrayList<>();
                weightList = new ArrayList<>();
                volumeStringList = new ArrayList<>();
                while ((lineTxt = bufferedReader.readLine()) != null) {
                    if (lineTxt.contains("the cubage of knapsack is")) {
                        volumeStringList.add(lineTxt);
                    }
                    if (lineTxt.equals("The profit of items are:")) {
                        String profit = bufferedReader.readLine();
                        profitList.add(profit);
                    }
                    if (lineTxt.equals("The weight of items are:")) {
                        String weight = bufferedReader.readLine();
                        weightList.add(weight);
                    }
                }
                read.close();
                return 1;
            } else {
                System.out.println("找不到指定的文件");
                return 0;
            }
        } catch (Exception e) {
            System.out.println("读取文件内容出错");
            e.printStackTrace();
        }
        return 1;
    }

绘制散点图模块代码

/**
     * 绘制图表
     */
    public static int drawchart(int[] profit, int[] weight) throws IOException {

        if (profit.length != 0 && weight.length != 0) {
            //设置散点图数据集
            XYSeries firefox = new XYSeries("weight/profit");
            for (int i = 0; i < profit.length; i++) {
                firefox.add(profit[i], weight[i]);
            }
            //添加到数据集
            XYSeriesCollection dataset = new XYSeriesCollection();
            dataset.addSeries(firefox);
            //实现简单的散点图,设置基本的数据
            JFreeChart freeChart = ChartFactory.createScatterPlot(
                    "数据散点图",// 图表标题
                    "weight",//y轴方向数据标签
                    "profit",//x轴方向数据标签
                    dataset,//数据集,即要显示在图表上的数据
                    PlotOrientation.VERTICAL,//设置方向
                    true,//是否显示图例
                    true,//是否显示提示
                    false//是否生成URL连接
            );
            //以面板显示
            ChartPanel chartPanel = new ChartPanel(freeChart);
            chartPanel.setPreferredSize(new java.awt.Dimension(560, 400));
            //创建一个主窗口来显示面板
            JFrame frame = new JFrame("Chart");
            frame.setLocation(500, 400);
            frame.setSize(600, 500);
            //将主窗口的内容面板设置为图表面板
            frame.setContentPane(chartPanel);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
            return 1;
        } else {
            return 0;
        }
    }
  • 测试运行
    读取相应的文件,选择文件中的数据进行图表的绘制

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

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

结果显示

  • 项目总结
    本次项目相对于自己来说难度比较大,查阅了许多资料浏览了许多网站才把这次项目拉入了正规,自己的编程能力比较弱,所以做起来也就比较费劲,加上此次实验不是有编程能力就足够的。所以在下次以及以后的实验项目中更要自己动手取完成。
posted @ 2022-03-21 15:53  王凯英  阅读(117)  评论(1编辑  收藏  举报