结对第二次作业
1.给出结对成员的学号及姓名
071503427 张岳
031502341 张富华
2.首页给出项目的Github链接。
项目地址:https://github.com/zyccccla/myWorks/tree/master/pair_work
3.贴出你们生成的一组最“好”的数据(给出对应链接即可),并详细说明"数据生成"程序的原理以及你们所考虑的因素。
最好的数据:https://github.com/zyccccla/myWorks/blob/master/pair_work/Project/src/input_data.txt
原理:将标签分组给每个学生和部门随机分配,将时间段设置为早上8:00到晚上10:00每两个小时为一个时间段,然后进行随机分配
4.详细说明你们数据建模及匹配程序的思路及实现方式。
- 数据建模
- 学生
基本信息:
- 兴趣标签
- 部门意愿
- 空闲时间
- 部门意愿(有优先级)
- 报名部门数量上限
- 编号
除了考虑基本信息外,还添加了一个字段用于记录学生当前获得部门允许的部门数
时间段的处理我们将不同的时间段转换成了数字方便和部门常规活动时间进行比较
- 部门
基本信息:
- 编号
- 上限人数
- 标签
- 常规活动时间
- 当前符合条件的人数
活动时间同样转换为数字处理,部门优先挑选当前部门意愿靠前的学生,这样可以较为人性的选择。
- 匹配算法
- 思路:
我们的想法比较简单,设定根据意愿、时间和兴趣作为第一优先级和第二优先级和第三优先级来进行筛选,第一轮筛选时先按照学生的意愿部门进行匹配,如果学生的时间符合部门的常规活动时间,则直接粗暴地加入到该部门的列表中,即部门的时间数字小于学生的话就视为匹配,此时暂不考虑部门人数限制的条件,但这样造成的结果就是代码的时间复杂度很大。第二轮筛选按照学生的兴趣,这里我们想了很久,决定用学生兴趣个数和学生报名部门数计算出一个兴趣的匹配值,初衷是为了让部门挑选到更合适的学生(但是这样报名部门少的人就会占有一定优势,只能勉强考虑部门希望挑选到更有时间充分为其服务的人,感觉这里应该想出更好的匹配方法)。第三轮筛选就是根据部门的上限人数,如果当前部门队列人数已满,则将队列末尾的学生移出当前部门队列。最后统计学生匹配成功数为0的人,加入无部门队列。
- 关键代码
`private void fitProcess(int index) {
for(int j = 0; j < Input.stu.length; j++) {
if(Input.stu[j].getChoice().length-1 >= index) {
String dept = Input.stu[j].getChoice()[index];
String no = Input.stu[j].getNo();
if(isFreeTimeConflict(index,dept) == false){
map.get(dept).add(no);
}
}
}
for(int i = 0; i < Input.depart.length; i++) {
String dno = Input.depart[i].getNo();
int num = Input.depart[i].getNumFree();
ArrayList<String> tmp = map.get(dno);
int newNum = 0;
if(num >= 0){
if(num >= tmp.size()) {
newNum = num - tmp.size();
result.get(dno).addAll(tmp);
Input.depart[i].setNumFree(newNum);
dealNumAdmit(tmp);
}
else {
tmp = filter(i,tmp,num);
newNum = num - tmp.size();
result.get(dno).addAll(tmp);
Input.depart[i].setNumFree(newNum);
dealNumAdmit(tmp);
}
}}`
- 不足
感觉我们的想法还是比较简单,导致写出的代码很臃肿,逻辑不是太清晰
兴趣匹配的算法考虑有些不周
有可能会出现在输入文件中排列靠前的学生更有优势,这是需要进一步优化的地方。
5.你们在代码遵循了一定的规范,在博客中描述结对团队遵循的代码规范,并截取部分关键代码佐证说明。
代码规范:变量统一采用下划线命名
方法用驼峰命名法命名
添加简单的注释
代码证明:
`public class Student {
private String s_no;
private String[] s_free;
private String[] s_cho;
private String[] s_tag;
int[][] time_change;
int num; //记录每个学生允许加入的部门数
Student(int dept_sz,int tag_sz,int free_sz) {
s_tag = new String[tag_sz];
s_cho = new String[dept_sz];
s_free = new String[free_sz];
time_change = new int[free_sz][2];
num = 0;
}`
private void readDepartments(JSONArray departments) {
final String DNO = "department_no";
final String DMEM = "member_limit";
final String DTAGS = "tags";
final String DSCH = "event_schedules";
for(int i = 0; i < DNUM; i++) {
JSONObject department = departments.getJSONObject(i);
String D_no = department.getString(DNO);
int D_mem = department.getInt(DMEM);
JSONArray D_tag = department.getJSONArray(DTAGS);
JSONArray D_sch = department.getJSONArray(DSCH);
if(depart[i] == null){
int tag_sz = D_tag.length();
int sch_sz = D_sch.length();
depart[i] = new Department(tag_sz,sch_sz);
}
depart[i].setNo(D_no);
depart[i].setMemberMax(D_mem);
for(int j=0;j<D_tag.length();j++){
depart[i].setTags(j, D_tag.getString(j));
}
for(int j=0;j<D_sch.length();j++){
depart[i].setEventSchedules(j, D_sch.getString(j));
}
depart[i].setDateTime();
}
}}
6.结果评估。
部门匹配结果为全部匹配,符合我们编写程序时考虑的要求
7.结对感受。
这次作业实在是完成的太仓促了,本身我的代码能力就不是很好,国庆还偷懒去玩了一下,导致和队友的交流也少了很多,在这里很感谢队友的包容。回来后才真正发现作业量的巨大,看到群里很多大神国庆都是和代码度过的,我感觉这就是差距吧,自己最后两天都是在紧张中度过的,被逼着也学了一些东西。虽然对java不是很熟练但是因为队友会java而且java处理json相对来讲比较方便就选择了java,发现了java确实很方便,之前学习js的时候简单接触过json,不过这次处理的时候还是遇到了很多麻烦,不停的Google 问人之后也算是艰难成长了一些。结对编程可以让自己更加轻易发现平时注意不到的小问题,而且和队友的代码融合的过程中我也发现了自己编写代码过程中的不足,我的注释写的很少这就给队友的阅读带来了很大的麻烦而且自己之后看的时候也要想很久,之后应该认真写注释了。在此立下不倒的flag,以后不能再拖了,实在是身心俱疲啊qaq。