zoukankan      html  css  js  c++  java
  • 软件工程实践:结对作业(第二次作业)

    作业地址

    结对第二次作业

    结对成员

    Github

    • Deputy: Department-to-Student bidirectional selection;
    • Deputy-generator:generate corresponding input JSON file for Deputy.

    数据生成程序, Deputy-generator

    一个生成的数据:input_data.json.

    数据生成原理

    部门:
    1.部门编号;
    2.部门纳新上限;
    3.部门固定活动时间;
    4.部门的兴趣标签

    学生:
    1.学号;
    2.选择的部门;
    3.业余时间;
    4.兴趣标签;
    5.是否被部门选中

    生成过程:
    学生:
    (第一步:生成除部门意愿以外的基本信息)

    • 按序生成学生学号(001-300);
    • 对于每一个学生,生成总数在范围[2, 8]之间的空闲时间段,分布一周7天,每个空闲时间段不超过3个小时,空闲时间段开始时间在[480, 1260],即早上八点到晚上九点之间;避免一天之内的空闲时间段的重叠,方法是将之前的时间段作为约束来生成下一时间段;
    • 随机选择兴趣标签数目,不作约束;
    • 生成数量在范围[1, 5]之间的部门意愿数目。
      (第二步:生成部门意愿)
      -首先生成热门部门的数量,经过商量确定为i【24】个,热门的占比为10,剩下的普通部门占比为4,这样我们就可以的到区间为【010i+4(20-i)】(作用在后面体现)
      -然后生成该学生一共选k个部门(k的范围是【1~5】)
      -最后依次生成k个部门,生成的方法是生成一个随机数,其范围是【0~10i+4(20-i)】(从第一步可以得到),然后根据生成的数我们就可以推出时选哪个部门,同时我们会生成一个数据用来存储前面选过的部门,避免重复选择。

    部门:

    • 按序生成部门编号(01-20);
    • 对于每一个部门,生成总数在范围[2, 5]之间的空闲时间段,分布一周7天,每个空闲时间段不超过3个小时,空闲时间段开始时间在[480, 1260],即早上八点到晚上九点之间;避免一天之内的空闲时间段的重叠,方法是将之前的时间段作为约束来生成下一时间段;
    • 随机生成范围在[10, 15]之间的人员限制;
    • 选择数目在[2, 5]之间的兴趣标签。

    考虑的因素

    1.热门部门的占比不同,会有更多的人去报名该部门。

    2.一周之内部门的活动时间最多不超过5次,每一天的活动次数不超过2次,每一次的活动时间不超过3个小时。

    3.学生的兴趣标签可以比较多,因为现在学生的特长更加广泛,但是部门的标签不能太多,因为部门本身就有自己的特色,倾向,这已经使其标签范围不可能太广。

    4.部门的活动时间是早上八点到晚上九点(符合实际,不可能大清早去活动)

    5.每个人分配一到两个部门,这样更加符合学生的实际状况,不会太过劳累,

    数据建模及匹配程序的思路及实现方式

    数据建模

    部门选择学生要考虑三个因素:学生选该部门是第几个志愿(同时也要考虑学生一共有几个志愿),学生兴趣标签和部门标签的匹配程度,学生的业余时间和部门固定活动时间的匹配程度。

    第一个因素(学生选该部门是第几个志愿(同时也要考虑学生一共有几个志愿)):
    显然越前面的志愿分值越高,学生选的志愿越少分值也会越高,同时为了使志愿之间的占比不是线性的(因为线性的区分度太低),这里就采用了取平方的方法。而学生志愿越少得分越高则想到了利用倒数的方法,而经过多次计算不同的值得到的结果,确定分子为2的时候,结果比较满意。
    所以得到这部分的计算公式:
    value1=(2/student_instance.applications_department_number)(5-k)(5-k)
    (其中student_instance.applications_department_number就是学生总得志愿数,k是该志愿是学生的第几志愿)

    第二因素(学生兴趣标签和部门标签的匹配程度):
    学生与部门标签的匹配度乘上某个数就是该部分的得分,而考虑了第一因素,发现第一因素的最高分为50,所以给第二因素的常量也为50。
    所以得到这部分的计算公式:
    value2=(match_tags/department_instance.tag_number)*50
    (其中match_tags是学生与部门标签的匹配的条数,department_instance.tag_number是部门总的标签数)

    第三因数(学生的业余时间和部门固定活动时间的匹配程度):
    根据现实情况,学生的业余时间越多越好,这样部门能更好的管理部员,而这个因素不能占太多的比重,毕竟头两个因素才是重点,所以这个因素是用来当做附加分的,分值也不高,大概在5分左右。
    所以得到这部分的计算公式:
    value3=times*stu_weekday_num/dep_weekday_num
    (其中times是学生与部门的时间匹配数,stu_weekday_num是学生的课余时间总数,dep_weekday_num是部门的固定活动时间总数)

    因此我们可以知道匹配值value=value1+value2+value3

    匹配程序的思路及实现方式

    具体方法定义看:matchAlgorithmTools.cpp
    具体实现过程看:matchAlgorithm.cpp

    下面是对过程的一个步骤分解

    第一步:
    将学生分为两类(有选志愿的和没选志愿的)
    调用matchAlgorithmTools.cpp的void deliverStudent()函数

    第二步:
    记录部门被学生选择的次数(分为0~4个志愿)

    (其中currentDepartment是当前部门,k是第几志愿)

    第三步:
    计算学生的权值(用于部门选择学生)
    调用matchAlgorithmTools.cpp的
    int matchedLevelValue(int k, students student_instance, departments department_instance)函数

    第四步:
    将部门按照受欢迎程度进行排序(之后热门部门将优先选择学生)
    调用matchAlgorithmTools.cpp的void calculateDepOrder()函数

    (计算的数组是由第二步得到algorithmTool.studentWishes二维数组)

    第五步:
    部门选择学生
    根据学生的value排序,拿出前department[currentDepartment].member_limit(就是部门收取人数的上限)个没被其他部门选走的学生加入当前的部门,完成分配。

    代码规范

    本次项目统一使用Github进行源代码管理,两人统一使用Wasdns账号进行提交。我们在结对过程中遵循以下规范:

    • 1.良好的注释习惯:对于每一个代码模块(一行或者多行,函数或者类)都进行详细的注释,保证队友能够理解
    • 2.参考"驼峰命名法"对变量进行命名,要求每一个变量的命名都是有意义的,且能够清楚地通过变量名了解该变量的作用
    • 3.进行异常的判断及处理

    代码佐证:

    	 /*
    	 * The following codes are used to: 
    	 *
    	 * 1.update studentWishes to calculate the order among departments.
    	 *
    	 * 2.calculate studentDepValues(student vs department) to find out
    	 *   that if the student is matched against the department or not.
    	 *   And for the following codes(i.e.L79), the studentDepValues is
    	 *   used to help the department choose students.
    	 * 
    	 */
    	
    	for (int i = 0; i < algorithmTool.eagerStudentNumber; i++) {
    		// current index of eagerStudents
    		int currentStudent = i;
    
    		// the total number of departments 
    		// that chosen by the current student
    		int depTotal = algorithmTool.eagerStudent[currentStudent].applications_department_number;
    		
    		// j: the number of departments
    		// k: the number of student wishes
    
    		// for each of the departments
    		for (int j = 0; j < 20; j++) {
    			int currentDepartment = j;
    			// the number of current department 
    			string currentDepartment_str = department[currentDepartment].department_number;
    
    			// check if the department 
    			// is the chosen one or not
    			for (int k = 0; k < depTotal; k++) {
    				// the k wish of current student
    				string kwish = algorithmTool.eagerStudent[currentStudent].applications_department[k];
    				
    				// if matched, means that 
    				// the student want this department
    				if (kwish == currentDepartment_str) {
    					// add 1 to studentWishes[department_number: currentDepartment][wishes: k]
    					algorithmTool.studentWishes[currentDepartment][k]++;
    
    					// calculate the value between current student 
    					// and current department based on k
    					// (the current number of wishes), the student instance 
    					// and the department instance  
    					int stuDepValue = algorithmTool.matchedLevelValue(k, algorithmTool.eagerStudent[currentStudent], department[currentDepartment]);
    					assert(stuDepValue != -1);
    					// record the stuDepValue 
    					// calculated by matchedLevelValue(...)
    					// in studentDepValues[student_instance_index][department_instance_index]
    					algorithmTool.studentDepValues[currentStudent][currentDepartment] = stuDepValue;
    					break;
    				}
    			}
    		}
    }
    

    结果评估

    运行了助教给的输入样例,结果如下:

    • 1.未匹配人数:190人,占比63%;
    • 2.未匹配部门:2个,占比10%;
    • 3.部门最多招纳人数:10人;
    • 4.部门平均招纳人数:5.5人。

    通过估算,平均每个部门收人上限为10~15个,最多要收取240人左右,而我们运行的结果显示有110人被部门收走,也就是收取人达到百分五十左右,去除和部门不匹配的人,百分五十是可以接受的数据。

    结对感受

    (1)结对感受:

    李鸣:这次结对作业,刚好我和我翔(队友)都是莆田人,所以就算是国庆放假也能够面基结对,整个国庆我们面基了5次,同时还语音结对了3次,可以说是整个国庆都是在结对中度过了,基本上也没消停过,说实话是很难受,毕竟是今年的最后一个法定节假日。但是,在和我翔的结对中也不乏乐趣,经我翔介绍发现了一家很有情趣的咖啡馆,听我翔说买上一杯咖啡可以在这度过一个下午,结对的过程中有让我印象最深的就是我翔的代码规范,真的做的很好,比起我的一团糟代码简直天差地别,这也让我明白了代码规范的重要性,在作业刚开始的时候我翔就自己做好了输入输出的工作,而我的工作主要就是想如何匹配,其他的部分则是我们一起思考,敲代码弄好的,这过程中也发现了结对带来的一个好处就是,敲代码的人头脑可能不会那么清晰,有时候一些小错误发现不了,而一旁的队友一般都会很容易发现这种小错误,节省了很多的时间。总得来说,这次结对是一次不错的体验,唯一的代价估计就是少了个国庆。

    陈翔:我能够深深体会到这两次结对的作业量,在多件事情并行的情况下国庆假期等于没放假了。这次结对,几天内近几k行的代码量,近百余次的Github项目管理记录(不算什么但是我觉得还是要列一下:D),和我鸣多次的电话讨论确定算法模型,见面敲定解决方案。虽然不是第一次和别人合作完成项目,但是本次结对依然获益颇多:一是收获了结对编程的经验,有旁边人实时code review的感觉还是很良好的,因为一个人的时候经常是这种情况:"写bug五分钟,debug两小时",在结对编程中就不会有这种情况的发生,避免了大量不必要时间的浪费,提高了整体效率,此外作为一个小团队也学习了一些团队协作的知识,比如编码规范,模块对接等等;二是充实(填满)了整个假期,提升了整体的编码水平,巩固了(再一次预习了)C++的知识,让我了解到很多Linux下编译、编程的知识以及之前未曾涉及到的JSON的解析方法;三是在结对过程中与我鸣多次交流结下了深厚(?)的友谊,虽然不时会被他和他的小可爱虐一脸,可是他幽默风趣、细心可爱、阳光帅气、有担当负责任,是一个不可多得的好搭档,编码过程中思路清晰,纠正了我不少的问题。

    我对于我鸣的建议有以下两点:

    • 1.编码过程中要时刻注意写注释和代码规范,变量命名时要合理清晰;
    • 2.Github commit的习惯,当你上手学会了Github之后,它会是一个非常棒的工具;
    • 3.好好珍惜女朋友,工作的时候女朋友的电话还是要接的。

    贴上我翔拍摄的咖啡馆(搞基好去处):

    以及店内一只猫(阿布,可撸!!),看见我的电脑包就坐上去了????

  • 相关阅读:
    springMVC+freemarker中Could not resolve view with name... 问题解决
    mybatis中if test 语句 当参数类型为string时,如何写判断条件
    博科交换机升级FOS系统
    response.redirect 和Server.Transfer 的区别
    win7 安装MyGeneration版本,没有安装mdac的解决办法
    Zen Cart的sidebox机制
    ASPCMS相册 实现每张图片对应一段文字
    ZEN CART 系统想在首页调用 新闻插件 的 新闻列表的方法
    JS获得来源页
    zen cart去掉zenid的简单方法
  • 原文地址:https://www.cnblogs.com/zxlmhh/p/7642836.html
Copyright © 2011-2022 走看看