201971010229-刘转弟 实验二 软件工程个人项目-《D{0-1} KP问题》

项目 内容
课程班级博客链接 2019级卓越工程师班
这个作业要求链接 作业要求
我的课程学习目标 1.掌握软件项目个人开发流程
2.掌握Github发布软件项目的操作方法
这个作业在哪些方面帮助我实现学习目标 1.熟悉并掌握GitHub与Eclipse的连接
2.熟悉java语言的开发步骤
3.进一步加深对折扣{0-1}问题的动态规划和回溯算法
4.熟悉使用java语言对文件的读取与导出
项目GitHub的仓库链接地址 仓库链接

1.实验目的与要求

(1)掌握软件项目个人开发流程。
(2)掌握Github发布软件项目的操作方法。

2.实验内容与步骤

任务1:点评班级博客中的作业
点评1
点评2
点评3
任务2:总结详细阅读《构建之法》第1章、第2章,掌握PSP流程
第一章

  • 软件=程序+软件工程
  • 程序=数据结构+算法
  • 软件企业=软件+商业模式
    如果把软件开发的不同阶段比作航天事业的发展,好比一个成熟的航空工业中,一个飞机发动机从构思到最后运行,不知道要经历过多少人、多少工序、多少流程、多少相关知识的验证,其中的过程对于常人来说是无法想象的。在软件开发的发展过程中,由最初的个体编程到小团体的编程,到现在一个成熟的团队的工程,原文中的图表给出了很清晰的对比过程。
  • 软件工程定义
    软件工程是把系统的、有序的、可量化的方法应用到软件的开发、运营和维护上的过程。软件工程包括下列领域:软件需求分析、软件设计、软件构建、软件测试和软件维护。软件工程和下列的学科相关:计算机科学、计算机工程、管理学、数学、项目管理学、质量管理、软件人体工学、系统工程、工业设计和用户界面设计。
    软件开发过程的五大难题:复杂性、不可见性、易变性、服从性、非连续性。
    第二章
    2.1单元测试

1.软件的很多错误来源于程序员对模块功能的误解,疏忽或不了解模块的变化。单元的测试可以让自己负责的模块功能定义尽量明确,模块功能的改变不会影响其他模块,而且模块的质量能得到稳定的、量化的保证。

2.创建单元测试的主要步骤:

  • 设置数据

  • 使用被测试类型的功能

  • 比较实际结果和预期的结果
    3.一个好的单元测试应当准确快速的保证程序基本模块的正确性。一个好的单元测试应该满足以下标准:

  • 单元测试应该在最基本的功能/参数上验证程序的正确性

  • 单元测试应该由最熟悉代码的人(程序的作者)来写

  • 单元测试过后机器的状态应保持不变

  • 单元测试要快

  • 单元测试应该产生可重复、一致的结果

  • 独立性-单元测试的运行/通过/失败不依赖别的测试,可以认为构造数据,以保持单元测试的独立性

  • 单元测试应该覆盖所有代码路径(100%的代码覆盖率不等于100%的正确性)

  • 单元测试应该集成到自动测试的框架中

  • 单元测试必须和产品代码一起保存维护
    4.回归测试:从正常工作的稳定状态退化到不正常工作的不稳定状态。 回归测试最好要自动化,这样可以对每一个构造快速运行所有的回归测试,以保证尽量早的发现问题。单元测试是回归测试的基础。

2.2效能分析工具

1.效能分析工具可以测试代码运行的效率,让程序员有针对性的对程序代码进行优化升级。

2.常用的方法有:

  • 抽样:当程序运行时 效能分析工具时不时的看看程序运行在哪一个函数里,程序运行结束就会得出一个程序运行时间的大致印象。不需要改动程序,可以很快找到瓶颈,但是不能准确表示代码中的调用关系树
  • 代码注入:将检验代码加入到每个函数中,这样程序得一举一动都会被记录下来。程序的各个效能数据都会被精准的测量,但是程序的运行时间会大大将长,还会产生很大的数据文件,增加了数据分析的时间,同时注入的程序代码也影响了程序真实得运行情况
    3.先抽样找到效能的瓶颈,然后对特定的模块用代码注入的方式进行详细分析。

2.3个人开发流程

1.个人开发流程:软件工程师开发软件的工作流程

2.PSP特点:

  • 不局限于某一种软件技术,而是着眼于软件的开发流程
  • 不依赖考试,而是要靠工程师自己收集数据,然后分析提高
  • 依赖于数据
  • PSP的目的是记录工程师如何完成实现需求的效率,而不是记录顾客对产品的满意度。
    任务3:项目开发背景
    1.需求分析
    背包问题(Knapsack Problem,KP)是NP Complete问题,也是一个经典的组合优化问题,有着广泛而重要的应用背景。{0-1}背包问题({0-1 }Knapsack Problem,{0-1}KP)是最基本的KP问题形式,在此之前,学习过{0-1}背包问题的动态规划算法以及回溯法,本实验中任务3-1要求读取所给TXT文件的有效D{0-1}KP数据,任务3-1是将其读取的有效数据以重量为横轴、价值为纵轴的数据散点图,任务3-3要求对一组D{0-1}KP数据按项集第三项的价值:重量比进行非递增排序,即递减排序,任务3-4是选择动态规划算法、回溯算法求解指定D{0-1} KP数据的最优解和求解时间(以秒为单位),任务3-5是将任务3-4中计算所得最优解、求解时间和解向量可保存为txt文件或导出EXCEL文件
    2.功能设计
  • 基本功能:
    (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文件。
    3.设计实现
    (1)ReadTheFil类 :通过文件路径来创建文件实例,把FileInputStream实例 传递到 BufferedInputStream,目的是能快速读取文件,最后,使用available检查是不是读到了文件末尾。
    (2)ScatterDiagram类 :创建二维数组data存储profit价值和height重量,以重量为横轴、价值为纵轴,建立直角坐标系画出散点图。
    (3)WeightRatio类 :分别定义int类型数组profit和weight数组将价值和重量存储,因为所给数据全部为int型,再定义比值ratio为double类型,再将其int类型数组强制转换为double进行比值运算,最后运用冒泡排序将比值进行降序排序。
    (4)Time类 :使用动态规划算法:在0/1背包问题中,物品i或者被装入背包,或者不被装入背包,设xi表示物品i装入背包的情况,则当xi=0时,表示物品i没有被装入背包,xi=1时,表示物品i被装入背包。

4.测试运行
(1)读入有效数据,如图1

图一
(2)绘制散点图,如图2:

图2
(3)重量比排序,如图3:

图3
(4)计算最优解及求解时间,如图4:

图4
5.代码片段

(1)读入实验数据文件的有效D{0-1}KP数据

//读取txt文件
	   File file = new File("E:\\测试数据\\beibao2.in");
      BufferedInputStream bis = null;
      FileInputStream  fis= null;
      try{
          //第一步 通过文件路径来创建文件实例
          fis = new FileInputStream(file);
          /*把FileInputStream实例 传递到 BufferedInputStream
                   目的是能快速读取文件
           */
          bis = new BufferedInputStream(fis);
          /*available检查是不是读到了文件末尾 */
          
          while( bis.available() > 0 ){                 
              System.out.print((char)bis.read());
          }
          
       }catch(FileNotFoundException fnfe)
        {
            System.out.println("文件不存在" + fnfe);
        }

        catch(IOException ioe)
        {
            System.out.println("I/O 错误: " + ioe); 
        }

(2)绘制散点图

int h = getHeight();//重量
	int w = getWidth();	//价值

	// 横坐标	
	g2.draw(new Line2D.Double(PAD, w-PAD, h-PAD, w-PAD));
	// 纵坐标
	g2.draw(new Line2D.Double(PAD, PAD, PAD, w-PAD));
	
	
	double xInc = (double)(w - 2*PAD)/(data.length-1);
	double scale = (double)(h - 2*PAD)/getMax();
	
	// 数据点(坐标)	
	g2.setPaint(Color.blue);//点的颜色
	
	for(int i = 0; i < data.length; i++) {
	double x = PAD + i*xInc;	
	double y = h - PAD - scale*data[i];	
	g2.fill(new Ellipse2D.Double(x-2, y-2, 4, 4));	

(3)重量比排序:

//冒泡排序
		double tmp;
		for (int a= 1; a < ratio.length; a++) {
			for (int j = 0; j < ratio.length-1; j++) {
				if(ratio[j] < ratio[j+1]){
					tmp = ratio[j];
					ratio[j] = ratio[j+1];
					ratio[j+1] = tmp;
				}
			}

(4)计算最优解及求解时间:

//1.创建二维数组
        //v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值
        int[][] v=new int[n+1][m+1];
        //存放记录数组
        int[][] path=new int[n+1][m+1];

        //2.初始化第一行第一列(已经处理了,因为默认是0)
        //3.根据公式来动态规划处理
        for (int i = 1; i < v.length; i++) {
            for (int j = 1; j < v[0].length; j++) {
                //公式
                if(w[i-1]>j){//因为我们程序i是从1开始的,因此原来的公式中的w[i]修改成w[i-1]
                    v[i][j]=v[i-1][j];
                }else{
                    //v[i][j]=Math.max(v[i-1][j],val[i-1]+v[i-1][j-w[i-1]]);
                    if(v[i-1][j]<val[i-1]+v[i-1][j-w[i-1]]){
                        v[i][j]=val[i-1]+v[i-1][j-w[i-1]];
                        path[i][j]=1;
                    }else{
                        v[i][j]=v[i-1][j];
                    }
                }
            }
        }

6.总结
刚拿到题目时,真的感觉这次实验非常难,而且还要使用GitHub创建仓库来与Eclipse相连接,又为这个作业增添了不少难度,因为我本身动手能力就较弱。在本次实验的具体实行过程中,我又熟悉重温了一遍Eclipse集成开发环境的项目搭建与运行,这次实验要求较多且很有难度,因为实验要求需要将Eclipse中的代码传到GitHub中,因此,必须要熟悉并掌握GitHub与Eclipse的连接,在连接的过程中遇到了很多困难,比如在最后一步时系统总是提示Eclipse无法连接github,尝试了很多方法,虽然我没有深刻理解这一步的作用,我添加好之后,系统还是提示不能连接,找了很多参考资料,在最后终于找到了一篇文章,解决了我很大一部分问题,这篇文章给了我很多的提示与帮助。
7.PSP展示

PSP 任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min)
Planning 估计这个任务需要多少时间,并规划大致工作步骤 8 15
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 8 15
Development 开发 168 291
Analysis 需求分析 (包括学习新技术) 20 25
Design Spec 生成设计文档 15 25
Design Review 设计复审 (和同事审核设计文档) 10 16
Coding Standard 代码规范 (为目前的开发制定合适的规范) 3 5
Design 具体设计 35 40
Coding 具体编码 45 90
Code Review 代码复审 10 30
Reporting 报告 9 11
Test Report 测试报告 3 5
Size Measuremen 计算工作量 3 2
Test 测试(自我测试,修改代码,提交修改) 30 60
Postmortem & Process Improvement Plan 事后总结 ,并提出过程改进计划 3 4
小结
   在本次实验中,我花费时间最长的就是具体编码部分,虽然之前也学习过JAVA语言,但是因为太久没有写过java程序,且很久没有复习具体的编程,导致我忘记了很多具体的细节,因此本次实验在这部分花费时间较长,而且在进行代码测试时,有时候会有很多bug,一时半会儿改不好,也花费了很多时间,但是好在java有写问题可以自动修改。而且我在制做PSP表格时,计划的时间过短,而实际使用时间过长,使两者之间的差距过大。在今后的实验过程中,我将会加强自己的编程能力,多写代码,强加练习,在平时的生活学习中勤加思考,在小组合作学习中也要多多思考,长善救失,取长补短。

任务4:将项目源码工程文件提交到Github账号的项目仓库
已完成项目托管,如图5

posted @ 2022-03-22 00:56  刘转弟  阅读(108)  评论(2编辑  收藏  举报