编程语言
首页 > 编程语言> > 201971010150-闫雨馨 实验三 结对实验 《{0-1}KP 实例数据集算法实验平台》

201971010150-闫雨馨 实验三 结对实验 《{0-1}KP 实例数据集算法实验平台》

作者:互联网

项目 内容
课程班级博客链接 2019级卓越工程师班
这个作业要求链接 实验三 软件工程结对项目
我的课程学习目标 1.提高软件项目开发中合作能力
2.提高代码编程能力
这个作业在哪些方面帮助我实现学习目标 1.体验软件项目开发中的两人合作,练习结对编程(Pair programming)
2.掌握Github协作开发软件的操作方法
结对方学号-姓名 201971010223-刘温元
结对方本次博客作业链接 结对方博客
本项目Github的仓库链接地址 Github仓库
  • 通过交流、实验、快速原型等方法,理解问题、需求或任务
  • 提出多种解决办法并估计工作量
    其中包括寻找以前的解决方案,因为很多工作是重复性的
  • 与相关角色交流解决问题的提案,决定一个可行的方案
  • 执行,把想法变成实际中能工作的代码,同时验证方案的可行性和其他特性(例如程序的效能等)
  • 和团队的其他角色合作,在测试环境中测试实现方案,修复缺陷(Bug)。如果此方案有严重的问题,那么久考虑其他方案
  • 在解决方案发布出去之后,对结果负责

1.交流:能有效地和其他队员交流,从大的技术方向,到看似微小的问题
2.说到做到:就像上面说到“按时交付”
3.接受团队赋予的角色并按角色要求工作:团队要完成任务,有很多事情要做,是否能接受不同的任务并高质量完成
4.全力投入团队的活动:就像一些评审会议,代码复审,就要全力以赴地参加,而不是游离于团队之外
5.按照团队流程的要求工作:团队有自己的流程,个人的能力即使,也要按照团队制定的流程工作,而不要认为自己不受流程约束
6.准备:在开会讨论之前,开始一个新功能之前,一个新项目之前,都要做好准备工作。
7.理性地工作:软件开发有很多个人的、感情驱动的因素,但是一个成熟的团队成员必须从事实和数据出发,按照流程,理性地工作。很多人认为自己需要灵感和激情,才能为宏大的目标奋斗,才能成为专业人士。著名的艺术家Chuck Close说:我总觉得灵感是属于业余爱好者的。我们职业人士只是每天持续工作。今天你继续昨天的工作,明天你继续今天的工作,最终你会有所成就
2.《现代软件工程—构建之法》第4章内容知识总结

主要是文字上的规定。代码风格的原则是:简明、易读、无二义性,包括对于缩进、行宽、括号、分行、命名、下划线、注释、大小写以及断行与空白的{}行的处理,具体如下:

  • 缩进:可以使用Tab键以及2、4、8等空格。个人认为依据不同是编程语言,可以使用不同的缩进方式。
  • 行宽:以前的计算机/打字机显示行宽为80字符,现在可以限定为100字符。
  • 括号:用括号清楚的表明逻辑优先级。
  • 断行与空白的{}行:主要是在多层循环中规范使用。
  • 分行:不要把多条语句放在一行上。
  • 命名:命名能够表明变量的类型及相应的语义,简洁易懂。
  • 下换线:合理使用来分隔变量名字中的作用域标注和变量的语义。
  • 大小写:多个单次组成的变量名,用大小写区分,例如著名的驼峰式命名法。
  • 注释:能够很好的解释程序是做什么的,以及为什么这样做。

不光是程序书写格式的问题,而且牵涉到程序设计、模块之间的关系、设计模式等的方方面面,主要有以下几个部分:

  • goto:函数最好有单一的出口,可以使用goto。
  • 函数:能够很好的完成一件事。
  • c++类的处理:注意类、classvc.struct、公共/保护/私有成员、数据成员、虚函数、构造函数、析构函数、new和delete、运算符、异常处理、类型继承等的规范设计。
  • 错误处理:预留足够的时间,使用的方法包括参数处理和断言。
  • 断言:使用断言来验证正确性。
  • 参数处理:在debug版本中,所有的参数都要验证其正确性。在正式版本中,对从外部(用户或别的模块)传递过来的参数,要验证其正确性。
  • 数据成员:数据类型的成员用m_ name说明。不要使用公共的数据成员,要用inline访问函数,这样可兼顾封装和效率。
  • 构造函数:不要在构造函数中做复杂的操作,简单初始化所有数据成员即可。构造函数不应该返回错误(事实上也无法返回)。把可能出错的操作放到HrInit()或FInit()中。
  • 异常:异常是在“异乎寻常”的情况下出现的,它的设置和处理都要花费“异乎寻常”的开销,所以不要用异常作为逻辑控制来处理程序的主要流程。了解异常及处理异常的花销,在C++语言中,这是不可忽视的开销。当使用异常时,要注意在什么地方清理数据。异常不能跨过DLL或进程的边界来传递信息,所以异常不是万能的。
  • 运算符:在理想状态下,我们定义的类不需要自定义操作符。确有必要时,才会自定义操作符。运算符不要做标准语义之外的任何动作。运算符的实现必须非常有效率,如果有复杂的操作,应定义一个单独的函数。当你拿不定主意的时候,用成员函数,不要用运算符。

看代码是否在代码规范的框架内正确地解决了问题。代码复审的三种形式:自我复审、同伴复审、团队复审。

  • 自我复审:用同伴复审的标准来要求自己。不一定最有效, 因为开发者对自己总是过于自信。如果能持之以恒,则对个人有很大好处。
  • 同伴复审:简单易行。
  • 团队复审:有比较严格的规定和流程,适用于关键的代码,以及复审后不再更新的代码。覆盖率高——有很多双眼睛盯着程序,但效率可能不高。

指一起分析,一起设计,一起写测试用例,一起做单元测试,一起做集成测试,一起写文档等等。

  • 角色:驾驶员:控制键盘输入;领航员:起到领航、提醒的作用。
  • 好处:在开发层次,可以提供更好的设计质量和代码质量,两人合作解决问题的能力更强;对开发人员,带来更多的信心,高质量的产出带来更高的满足感;企业管理层次上,有效地交流,相互学习和传递经验,分享知识,取得更高的投入产出比。
  • 好处:每人在各自独立设计、实现软件的过程中不免要犯这样那样的错误。在结对编程中,因为有随时的复审和交流,程序各方面的质量取决于一对程序员中各方面水平较高的那一位。这样,程序中的错误就会少得多,程序的初始质量会高很多,这样会省下很多以后修改、测试的时间。
项目成果评价 内容
结对方 201971010223-刘温元
结对方实验二博客作业链接 对方博文链接
结对方实验二的Github的仓库链接地址 仓库链接
  • 博客结构:
    博文整体排版较好,清晰可读,但是在内容上应该改进,更加详细一点。
  • 博文内容:
    实验内容完成度不错,基本实现了实验二中的要求,并对需求分析、功能设计及设计实现设计实现都进行了详细的称述。
  • 博文结构与PSP中“任务内容”列的关系:
    博文严格按照PSP的各个流程进行撰写,整体完成度很好。
  • PSP中“计划共完成需要的时间”与“实际完成需要的时间”两列数据的差异化分析与原因探究:
    实际完成需要的时间总是比计划共完成需要的时间要多,下次再制定计划共完成需要的时间可以进行适当的改进。
核查表 执行情况
概要部分
代码符合需求和规格说明么? 代码基本符合需求
代码设计是否考虑周全? 比较周全
代码可读性如何? 可以顺利阅读
代码容易维护么? 不太容易维护
代码的每一行都执行并检查过了吗? 检查过了都可执行
设计规范部分
设计是否遵从已知的设计模式或项目中常用的模式? 基本遵从
代码有没有依赖于某一平台,是否会影响将来的移植(如Win32到Win64)? 没有影响
开发者新写的代码能否用已有的Library/SDK/Framework中的功能实现?
在本项目中是否存在类似的功能可以调用而不用全部重新实现?
能,存在
有没有无用的代码可以清除?(很多人想保留尽可能多的代码,因为以后可能会用上,这样导致程序文件中有很多注释掉的代码,这些代码都可以删除,因为源代码控制已经保存了原来的老代码)
代码规范部分
修改的部分符合代码标准和风格么? 不符合
具体代码部分
有没有对错误进行处理?
对于调用的外部函数,是否检查了返回值或处理了异常?
进行了处理,检查了并处理了异常
参数传递有无错误,字符串的长度是字节的长度还是字符(可能是单/双字节)的长度,是以0开始计数还是以1开始计数? 无错误;本项目中是以0开始计数。
边界条件是如何处理的?
switch语句的default分支是如何处理的?
循环有没有可能出现死循环?
switch语句的default分支返回false,没有出现死循环。
有没有使用断言(Assert)来保证我们认为不变的条件真的得到满足? 没有
对资源的利用是在哪里申请,在哪里释放的?
有没有可能导致资源泄露(内存、文件、各种GUI资源、数据库访问的连接,等等)?
有没有优化的空间?
在内存中完成,有可能泄露
数据结构中有没有用不到的元素? 没有
效能
代码的效能(Performance)如何?
最坏的情况如何?
基本达到要求
代码中,特别是循环中是否有明显可优化的部分(C++中反复创建类,C#中 string 的操作是否能用StringBuilder 来优化)?
对于系统和网络调用是否会超时?
如何处理?
不会
可读性
代码可读性如何?
有没有足够的注释?
可顺利阅读,有足够的注释
可测试性
代码是否需要更新或创建新的单元测试?
针对特定领域的开发(如数据库、网页、多线程等),可以整理专门的核查表
需要
PSP2.1 任务内容 计划完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划 60 80
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 70 85
Development 开发 2650 2850
Analysis 需求分析 (包括学习新技术) 60 60
Design Spec 生成设计文档 50 60
Design Review 设计复审 (和同事审核设计文档) 60 60
Coding Standard 代码规范 (为目前的开发制定合适的规范) 40 50
Design 具体设计 80 85
Coding 具体编码 2000 2300
Code Review 代码复审 180 200
Test 测试(自我测试,修改代码,提交修改) 150 160
Reporting 报告 200 210
Test Report 测试报告 60 60
Size Measurement 计算工作量 50 55
Postmortem & Process Improvement Plan 事后总结 ,并提出过程改进计划 120 150
private void dfs(int x){
    back_count++;
    if(back_count>INF){
        res=-1;
        return ;
    }
    if(x>=row) {
        return ;
    }
    else {
        if(weight[x+1][2]<=back_weight) {
            back_weight-=weight[x+1][2];
            back_value+=value[x+1][2];
            if(res<back_value) {
                res=back_value;
            }
            dfs(x+1);
            back_weight+=weight[x+1][2];
            back_value-=value[x+1][2];
        }
        dfs(x+1);
        if(weight[x+1][0]<=back_weight) {
            back_weight-=weight[x+1][0];
            back_value+=value[x+1][0];
            dfs(x+1);
            if(res<back_value) {
                res=back_value;
            }
            back_weight+=weight[x+1][0];
            back_value-=value[x+1][0];
        }
        if(weight[x+1][1]<=back_weight) {
            back_weight-=weight[x+1][1];
            back_value+=value[x+1][1];
            if(res<back_value) {
                res=back_value;
            }
            dfs(x+1);
            back_weight+=weight[x+1][1];
            back_value-=value[x+1][1];
        }
    }
}
private Long knapSack(int[] weight, int[] profit, int C)
{
    int n = profit.length/3;//profit一定是3的倍数
    int[][] maxvalue = new int[n + 1][C + 1];//价值矩阵
    long before=System.currentTimeMillis();
    for (int i = 0; i < maxvalue.length; i++) {
        maxvalue[i][0] = 0;
    }
    for (int i = 0; i < maxvalue[0].length; i++) {
        maxvalue[0][i] = 0;
    }
    for (int i = 1; i < maxvalue.length; i++) {//不处理第一行
        for (int j = 1; j <maxvalue[0].length; j++) {//不处理第一列
            //处理每一个项集
            int index=(i-1)*3;//计算当前的索引值,这里以项集为单位进行计算
            ArrayList<Integer> item=new ArrayList<>();
            if (j<weight[index]&&j<weight[index+1]&&j<weight[index+2])
            {
                maxvalue[i][j]=maxvalue[i-1][j];
                continue;
            }
            if(j>=weight[index])
                item.add(Math.max(maxvalue[i-1][j],profit[index]+maxvalue[i-1][j-weight[index]]));
            if(j>=weight[index+1])
                item.add(Math.max(maxvalue[i-1][j],profit[index+1]+maxvalue[i-1][j-weight[index+1]]));
            if(j>=weight[index+2])
                item.add(Math.max(maxvalue[i-1][j],profit[index+2]+maxvalue[i-1][j-weight[index+2]]));

            item.sort((Integer o1, Integer o2)->{
                if (o1>o2) return -1;
                else if (o1==o2) return 0;
                else return 1;
            });
            maxvalue[i][j]=item.get(0);
        }
    }
    long after=System.currentTimeMillis();
    this.setOptimalSolution(maxvalue[n][C]);
    return (after-before);
}

遗传算法:

// 初始化种群
private void initGroup() {
    int k, i;
    for (k = 0; k < scale; k++)// 种群数
    {
        // 01编码
        for (i = 0; i < LL; i++) {
            oldPopulation[k][i] = random.nextInt(65535) % 2;
        }
    }
}

private best_one evaluate(int[] chromosome) {
    // 010110
    int vv = 0;
    int bb = 0;
    int str[]=new int[LL];
    // 染色体,起始城市,城市1,城市2...城市n
    for (int i = 0; i < LL; i++) {
        if (chromosome[i] == 1) {
            int temp=random.nextInt(65535) % 64;
            if(temp<2) {
                vv += v[i][temp];
                bb += b[i][temp];
                str[i] = temp + 1;
            }
            else{
                vv += v[i][2];
                bb += b[i][2];
                str[i] = 3;
            }
        }
        else {
            str[i]=0;
        }
    }
    if (bb > pb) {
        // 超出背包体积
        best_one x =new best_one();
        x.x=0;x.y=str;
        return x;
    } else {
        best_one x =new best_one();
        x.x=vv;x.y=str;
        return x;
    }
}

// 计算种群中各个个体的累积概率,前提是已经计算出各个个体的适应度fitness[max],作为赌轮选择策略一部分,Pi[max]
private void countRate() {
    int k;
    double sumFitness = 0;// 适应度总和

    int[] tempf = new int[scale];

    for (k = 0; k < scale; k++) {
        tempf[k] = fitness[k];
        sumFitness += tempf[k];
    }

    Pi[0] = (float) (tempf[0] / sumFitness);
    for (k = 1; k < scale; k++) {
        Pi[k] = (float) (tempf[k] / sumFitness + Pi[k - 1]);
    }
}

// 挑选某代种群中适应度最高的个体,直接复制到子代中
// 前提是已经计算出各个个体的适应度Fitness[max]
private void selectBestGh() {
    int k, i, maxid;
    int maxevaluation;
    int max_str[] = null;

    maxid = 0;
    maxevaluation = fitness[0];
    for (k = 1; k < scale; k++) {
        if (maxevaluation < fitness[k]) {
            maxevaluation = fitness[k];
            max_str=fitness_str[k];
            maxid = k;
        }
    }

    if (bestLength < maxevaluation) {
        bestLength = maxevaluation;
        best_str=max_str;
        bestT = t;// 最好的染色体出现的代数;
        for (i = 0; i < LL; i++) {
            bestTour[i] = oldPopulation[maxid][i];
        }
    }

    // 复制染色体,k表示新染色体在种群中的位置,kk表示旧的染色体在种群中的位置
    copyGh(0, maxid);// 将当代种群中适应度最高的染色体k复制到新种群中,排在第一位0
}

// 赌轮选择策略挑选
private void select() {
    int k, i, selectId;
    float ran1;
    for (k = 1; k < scale; k++) {
        ran1 = (float) (random.nextInt(65535) % 1000 / 1000.0);
        // System.out.println("概率"+ran1);
        // 产生方式
        for (i = 0; i < scale; i++) {
            if (ran1 <= Pi[i]) {
                break;
            }
        }
        selectId = i;
        copyGh(k, selectId);
    }
}

private void evolution() {
    int k;
    // 挑选某代种群中适应度最高的个体
    selectBestGh();
    // 赌轮选择策略挑选scale-1个下一代个体
    select();
    float r;

    // 交叉方法
    for (k = 0; k < scale; k = k + 2) {
        r = random.nextFloat();// /产生概率
        // System.out.println("交叉率..." + r);
        if (r < Pc) {
            // System.out.println(k + "与" + k + 1 + "进行交叉...");
            OXCross(k, k + 1);// 进行交叉
        } else {
            r = random.nextFloat();// /产生概率
            // System.out.println("变异率1..." + r);
            // 变异
            if (r < Pm) {
                // System.out.println(k + "变异...");
                OnCVariation(k);
            }
            r = random.nextFloat();// /产生概率
            // System.out.println("变异率2..." + r);
            // 变异
            if (r < Pm) {
                // System.out.println(k + 1 + "变异...");
                OnCVariation(k + 1);
            }
        }

    }

}


// 两点交叉算子
private void OXCross(int k1, int k2) {
    int i, j, flag;
    int ran1, ran2, temp = 0;

    ran1 = random.nextInt(65535) % LL;
    ran2 = random.nextInt(65535) % LL;

    while (ran1 == ran2) {
        ran2 = random.nextInt(65535) % LL;
    }
    if (ran1 > ran2)// 确保ran1<ran2
    {
        temp = ran1;
        ran1 = ran2;
        ran2 = temp;
    }
    flag = ran2 - ran1 + 1;// 个数
    for (i = 0, j = ran1; i < flag; i++, j++) {
        temp = newPopulation[k1][j];
        newPopulation[k1][j] = newPopulation[k2][j];
        newPopulation[k2][j] = temp;
    }

}

// 多次对换变异算子
private void OnCVariation(int k) {
    int ran1, ran2, temp;
    int count;// 对换次数
    count = random.nextInt(65535) % LL;

    for (int i = 0; i < count; i++) {

        ran1 = random.nextInt(65535) % LL;
        ran2 = random.nextInt(65535) % LL;
        while (ran1 == ran2) {
            ran2 = random.nextInt(65535) % LL;
        }
        temp = newPopulation[k][ran1];
        newPopulation[k][ran1] = newPopulation[k][ran2];
        newPopulation[k][ran2] = temp;
    }
}

private void solve() {
    int i;
    int k;

    // 初始化种群
    initGroup();
    // 计算初始化种群适应度,Fitness[max]
    for (k = 0; k < scale; k++) {
        best_one temp= evaluate(oldPopulation[k]);
        fitness[k]=temp.x;
        fitness_str[k]=temp.y;
    }

    // 计算初始化种群中各个个体的累积概率,Pi[max]
    countRate();

    for (t = 0; t < MAX_GEN; t++) {
        evolution();
        // 将新种群newGroup复制到旧种群oldGroup中,准备下一代进化
        for (k = 0; k < scale; k++) {
            for (i = 0; i < LL; i++) {
                oldPopulation[k][i] = newPopulation[k][i];
            }
        }
        // 计算种群适应度
        for (k = 0; k < scale; k++) {
            best_one temp= evaluate(oldPopulation[k]);
            fitness[k]=temp.x;
            fitness_str[k]=temp.y;
        }
        // 计算种群中各个个体的累积概率
        countRate();
    }
}
public boolean getAllParameterByFile(String filePath) throws IOException {
    //若目录不存在,则创建目录
    File file=new File(filePath);
    String data= FileUtils.readFileToString(file,"UTF-8");
    //初步格式化件
    String getTextByDeleteWhiteSpace=StringUtils.deleteWhitespace(data);//删除所有的空格
    if (getTextByDeleteWhiteSpace.charAt(2)=='*') {
        int getFirstDKPIndex = getTextByDeleteWhiteSpace.indexOf("DKP");//获得首次出现DKP的位置
        String formatPrefixText = getTextByDeleteWhiteSpace.substring(getFirstDKPIndex + 3);//删除冒号以前的字符
        int getLastFullIndex = formatPrefixText.lastIndexOf('.');//获得最后一次出现.的位置
        int getLastCommaIndex = formatPrefixText.lastIndexOf(',');//获得最后一次出现,的位置
        int index = getLastFullIndex > getLastCommaIndex ? getLastFullIndex : getLastCommaIndex;//获得格式化后的文本
        String formatSuffixText = formatPrefixText.substring(0, index);
        getProfitAndWeight(formatSuffixText);//获取profit和weight
        return true;
    }else{
        return false;
    }
}

标签:复审,int,代码,maxvalue,201971010150,闫雨馨,++,实验,数据
来源: https://www.cnblogs.com/sankdd/p/16093986.html