结队项目——第二次作业
1、结对信息:
姓名 | 学号 | 班级 |
---|---|---|
王钦泽 | 031502232 | z |
吴晓晖 | 031502235 | k |
2、输入数据生成:
输入数据程序原理简要:
首先,将兴趣标签,部门面试时间段,学生空闲时间段,部门编号,学生学号等作为字符串保存到String数组里面。
(ps:当然也可以采用集合,枚举类等等达到一样的效果)。
其次,分别循环生成300个学生json对象以及20个部门json对象装入各自对应的jsonArray数组里面。其中,采用随机数生成程序达到兴趣标签,部门面试时间段,学生空闲时间段的随机筛选,做到充分随机。有一个需要注意的地方是随机筛选的时候,兴趣标签,偏爱部门不能重复,也是因为写了这个程序才学到了,随机生成一定范围内不重复数字的一些算法以及效率的比较。参考自博客链接,其中第三种方法是真的很妙,将指定范围的数都先填入source数组,之后随机产生0-len的索引index,将source[index]填入结果集result,之后len自减1(len为指定范围所有数的个数),原source[index]用source[len]替换,这样子每次随机出来的索引对应的数都不会重复,大大节省了时间。
(ps:做过一次实验,采用最基本的方法,即每次回溯已经筛的数,看是否重复,采用这种方法生成,半小时都跑不出数据来,而采用第三种方法,基本上是秒出。再次体会到好的算法真的是非常重要。)
2、数据建模及匹配程序实现:
数据建模及存储方式:
首先,通过judgeArray矩阵存放某学生是否申请某部门的true Or false 标志,之后利用SatisficalArray满意度匹配矩阵遍历学生和部门对象,检查某学生和某部门的匹配程度,转化成int值存入匹配矩阵中,可根据个人给面试时间匹配或者兴趣标签配对设置一个权值,来表示两者重要性强弱,我这里是综合考虑,并且如果学生的时间完全包含部门的时间的时候,即在某个部门面试时间段学生完全有空,则时间所加的匹配度更大,如果是部分包含,则相对较小一些,如若两者交集完全为空,则贡献度为0。
匹配程序实现思路:
基于以上相关数据存储和数据处理的准备,下一步就该进行部门和学生的匹配了。这里我的思路是这样的,以学生为主导对象,一共有三轮选择。第一轮遍历所有学生,并且在其所申请部门中选择匹配度最大的优先入选,部门不满则优先预选,如果部门满了,则与部门中已经预选上的学生的匹配度进行比较,大的替换预选中最小匹配度的学生,这样子做到学生方面优先进入意向部门里面匹配度最大的部门,而部门方面则优先选择匹配度最大的学生。第二轮和第一轮步骤和算法是一样的,对于经过第一轮还未被选上的学生进行第二匹配度竞选,即选择所选部门中第二匹配部门预选,以下步骤便和第一轮是一样的,做到匹配度优先。而所谓的第三轮,则是对经过第一,第二轮还未被选上的学生,对其剩下所选择部门进行最大能力匹配,即如果该部门还有空位置便直接入选,不进行匹配度配比,尽可能满足大多数学生都能够选到部门。
(ps: 偶然发现此题和某个数学模型很像,具体参考层次分析模型)
具体流程:
ps:分享一个流程图,思维导图在线制作网站,ProcessOn。
3、代码规范:
什么是代码规范?随着公司的业务发展,项目越来越多,越来越大,复杂性也越来越高。查找一个BUG变得越发抓狂,因此便需要有一定的代码规范,提高代码的易读性,加快编程以及查找bug的效率。
常见的一些代码规范,查找了一些大佬博客,发现一些常见的开发规范。 ① 代码规范、如何写出好代码 ② 再谈开发中的代码规范
在本次编码中,由于我是个新手,编程经验也不够丰富,因此写出来的代码大多是面向过程式的最朴素的代码(这点希望以后可以慢慢改进,能够用面向对象的四维审视世界),比如我最初写出来的代码全部都是集合到一个main函数中的,完全的面向过程,难以读懂,而且代码有冗余,又拖拉又长,当然常见的缩进格式以及注释是有的,看了队友的程序代码的我才意识到这一点,因此我又着手将main函数中的一些数据处理,匹配程序等独立分割成一个个类,通过类对象实例化调用方法。
代码如下:
for (int i = 0; i < ReadJson.StudentLength; i++) {
int max = 0;
int flag = -1;
boolean flag0 = false;
for (int j = 0; j < ReadJson.DepartmentLength; j++) {
//System.out.print(" " + SatisficalArray[i][j]);
if (judgeArray[i][j]) {
if (max < SatisficalArray[i][j]) {
max = SatisficalArray[i][j];
flag = j; //flag表示暂时分配给编号为flag的部门,并且max代表匹配度
flag0 = true;
}
} //寻找最大匹配度的部门
}
if (!flag0) {
continue;
} else {
SatisficalArray[i][flag] = 0;
if (departments[flag].menber < departments[flag].getLimit_number()) {
students[i].setIsunlucky(true);
students[i].setAdmittedBy(departments[flag].getDepartment_no());
departments[flag].Admittedstu[0][departments[flag].menber] = i; //学生编号i
departments[flag].Admittedstu[1][departments[flag].menber] = max; //匹配度max //纳入部门成员矩阵
departments[flag].menber++;
} //部门预选不满直接塞进去
else {
int temp;
int min = 65535;
int flagmin = -1;
int flagtag = -1;
for (int a = 0; a < 15 && departments[flag].Admittedstu[0][a] != 0; a++) {
if (min > departments[flag].Admittedstu[1][a]) {
min = departments[flag].Admittedstu[1][a];
flagmin = departments[flag].Admittedstu[0][a]; //flagmin最小匹配度学生编号
flagtag = a;
}
}
if (max > min) {
students[flagmin].setIsunlucky(false);
students[flagmin].setAdmittedBy("");
departments[flag].Admittedstu[1][flagtag] = max;
departments[flag].Admittedstu[0][flagtag] = i;
students[i].setIsunlucky(true);
students[i].setAdmittedBy(departments[flag].getDepartment_no());
} //匹配度比最小的大则替换
} //部门预选满了先比较
}
} //第一轮预选,学生方面优先进入意向部门里面匹配度最大的部门,部门方面优先选择匹配度最大的学生
其中一些if else没有注释,flag没有注释,可能比较难懂,数组变量命名按照英文格式命名,没有添加_等分割符号。一些希望以后在代码编程中逐步改进,形成自己的编程习惯。
“我无法想象这些连最最基本的编程素养都达不到的人,在编程方面会很优秀。”
发现一款常见格式化工具astyle-百度百科。
在网上搜罗,看到四句话:
1.这些规范都是官僚制度下产生的浪费大家的编程时间、影响人们开发效率, 浪费时间的东西。
2. 我是个艺术家,手艺人,我有自己的规范和原则。
3.规范不能强求一律,应该允许很多例外。
4.我擅长制定编码规范,你们听我的就好了。
这里发表一下个人看法: 第一点,前期学习代码规范可能会相对比较枯燥和无聊,但是在大的项目开发或者团队之间,统一代码规范是一件非常好的事情,提高代码在团队之间的易读性,加强团队之间的交流,在软件开发过程中常常能达到事半功倍的效果。至于第二点,我觉得艺术家和手艺人可以有自己的特色,但是软件开发不是个人的事情,涉及到后期的维护和更新,不能只强调自己的规范和原则,否则艺术家和手艺人也仅仅只是活在自己世界中的“艺术人”罢了。第三点,每个公司有每个公司的代码规范标准,规范的不一律性有很多例子,可以有例外,但大体要符合团队代码标准。第四点,每个人主张的代码规范一般都是不一样的,同样的话也适用于团队,团队需要与外界交流,也必须遵循外界一些普遍的代码规范,而不是只活在自己的团队中,那样是没有多大可发展性的。
4、结果评估:
我们两个人一共写了两种想法的实现,第一种是以上所述的那种,由于第三轮选择的很大程度上尽最大能力的分配,因此有部分可能不尽如人意,比如匹配度小的学生进入某部门,而匹配度大的学生则只能在门外观望。过分强调了第一志愿和第二志愿的重要性。而第二种想法是队友提出来的:本程序用于分配申请部门学生
- 输入格式:json,地址:.ininput_data.txt
- 输出格式:json,地址:.inoutput_data.txt
- 分配方案如下:
- 1轮:分配第一志愿,筛选掉第一志愿中不能满足部门活动时间有空的
- 如果部门人数未超过成员上限:分配第二志愿,筛选掉第二志愿中不能满足部门活动时间有空的
- 以此类推
- 2轮:如果部门没有超过成员上限,按个人兴趣以及满足部门活动时间分配学生
- 3轮:如果部门没有超过成员上限,按能否满足部门活动时间分配学生
相对来说更加人性化并且合理,既强调了时间的重要性也强调了第一志愿第二志愿以及个人兴趣的重要性,这样子得出的数据更加好一些。
注:国庆前讨论此题该怎么做,比如json解析,国庆时,两个人各自实现了不同的分配方案。
队友博客清戳
5、结队心得以及项目总结:
我的心得及总结:
首先,这次结队编程让我学会了很多,明白了一个小团队的重要性以及代码规范的重要性, 又让我对项目编程过程有了一定的体会和理解。不得不说,软工实践真是磨砺一个人的最好的方式了。以上很多工具和插件的使用,如果不是经历这次结队编程,我是不可能去了解的,在此非常感谢这次实践。总结一下在这次结队编程中所得:①对于一个代码经验不是很丰富的萌新的我,开始尝试使用eclipse这款强大的软件进行编程,熟悉了其中一些常用快捷键的使用,参考自博客。
②由于团队编程中要求一定的代码规范,因此在上述中参考了并且学习了一些常见的代码规范,对代码规范有一定的理解和感受,相信以后会经常和代码规范打交道的~。详情可见上述第三点。
③经过观看队友的代码,得到队友的指点,体会了面向对象的重要性,希望能加强自己编码能力,摆脱朴素的面向过程,更快拥有面向对象的思想和编程习惯。
④通过相关博客以及慕课网的学习熟悉了Json数据格式(一种轻量级的数据交换格式)以及常见的使用方式(详情请见),了解了json更为强大的Gson,留待以后进一步学习。
⑤学习了生成指定范围不重复随机数的一种非常快速的算法,大开眼界。
⑥在打包jar包的时候,发现用eclipse自带的打包工具不能将外部依赖包一起上传,经过网上查阅,最终学习并且使用Fat Jar 这款打包插件,非常好用而且方便。
⑦在编程结束后,利用jar包生成exe可执行文件。参考自博客