第六次作业--结队编程第二次
1、结队信息
学号 | 姓名 | 博客链接 |
---|---|---|
618 | 炜坤(po主) | 链接 |
616 | 语恳 | 链接 |
2、gayhub地址
3、设计说明
-
接口设计(API)
void Generate_JSON(int N,int M); //随机产生需要输入的数据(需要部门数和学生数)
void ReadJson(Department* &department, Student* &student,int N,int M); //读入json文件
void match(Department* &department,Student* &student,int N,int M); //部门匹配学生
void output(Department* department, Student* student, int N, int M) //输出匹配结果
-
内部实现设计(类图)
学生类属性包括:学号、姓名、性别、绩点、兴趣标签、空闲时间表、部门志愿表、选中部门数量、选中部门表。
部门类属性包括:部门编号、部门名称、人数限制、活动时间表、部门标签、绩点限制、报名学生权值表、报名学生数量、报名学生表
-
匹配算法设计
- 以部门为视角,最外层循环为部门遍历,内层循环为每个部门从全体学生筛选出有填报该部门志愿的学生,先将其招进部门学生表,计算每个申请者的权值(兴趣标签匹配一个加4分,空闲时间匹配一个加4分,高于绩点要求加10分,低于绩点要求不加分),并更新部门的学生选中个数。
- 若超出人数限制,在新学生加进表之前遍历部门学生表,比较其权值,将权值较大的选中,表中权值较低的淘汰。
- 在一个部门筛选完所有学生后,将选中信息更新到学生的选中部门表内,并更新学生的部门选中个数。
-
测试数据生成
创建一个数据生成器的头文件DataGenerator.h及类DataGenerator(包括各项属性的生成方式),分别定义定部门数据生成、学生数据生成(引用部门类和学生类)。
学生:学号(S0315xxxx),姓名(AZxxx),性别(female/male),绩点(15分),兴趣标签(25个),空闲时间(210个),部门志愿(2~5个)。
部门:编号(AZx),部门名称(同学生),人数限制(015人),活动时间(15个),标签(35个),绩点限制(1~3分)。
有关字符串方面的数据均通过定义固定的string数组,随机生成数组下标来达成随机字符串的目的。
基于最大数据(100,5000),学号和部门号均不重复,现阶段的随机形式也够用了,但这些数据离现实还是有很多差距,有待改进。
-
如何评价自己的匹配算法?
在权值计算方面还不够完善,只是通过简单的符合度累加,虽然能够做到让部门招满的地步,但离真正最优分配还有很大一段距离。
本程序的匹配算法有待优化,部门遍历学生太多,存在冗余代码,性能不佳。
4、关键代码解释
志愿匹配函数:
- 用于将学生与部门进行匹配的函数,函数中包含对学生评分的筛选。
- 该函数针对单个单个部门和单个学生,具体要求多个部门对多个学生可在外部加入双重循环。部门根据当前学生的志愿进行查找,寻找是否有本部门的部门号,如果有则匹配,没有则跳出。匹配到学生时,首先判断本部门是否已达到人满,如果人未满,则直接将其放入预选名单中,并记录其评分,如果人满,则需要将该学生的评分算出,与预选名单中的学生评分进行比较,若发现该学生评分大于预选表中某学生的评分则将其放入预选表中,并将评分较低的学生淘汰。
void Department::willmatching(Student &s)
{
if (D_Limit != 0)
{
for (int i = 0; i < 5; i++)
{
if (s.S_Choice[i] == D_No)
{
if (numofstu < D_Limit)
{
student[numofstu] = s.S_No;
m[numofstu] = cmp(s.GPA, s.S_Schedules, s.S_Tags, GPA_Limit, D_Schedules, D_Tags);
numofstu++;
}
else if (numofstu > D_Limit)
{
m[numofstu] = cmp(s.GPA, s.S_Schedules, s.S_Tags, GPA_Limit, D_Schedules, D_Tags);
for (int u = 0; u < D_Limit; u++)
{
if (m[numofstu] > m[u])
{
m[u] = m[numofstu];
student[u] = student[numofstu];
break;
}
}
}
}
}
}
}
评分计算函数
- 用于计算各学生的评分,根据不同的条件要求,对学生进行评分,算出部们对学生的总评分。
- 对于学生的兴趣条目与部门的兴趣要求进行匹配,发现一个相同的对该学生评分加4分,两个加8分,一次类推。同理对时间表也是发现一个相同的加4分,对于绩点要求,学生绩点高于部门要求绩点,评分加十分。
int cminterests(string* s_interest, string* d_interest)
{
int i, j, n = 0, n1 = 0, mark = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < n1; j++)
{
if (s_interest[i] == d_interest[j])
{
mark = mark + 1;
}
}
}
mark = mark * 4;
return mark;
}
int cmschedual(string* s_che, string* d_che)
{
int i, j, n = 0, n1 = 0, mark = 0;
for (i = 0; i < 10; i++)
{
if (s_che[i] == "")break;
for (j = 0; j < 5; j++)
{
if (d_che[j] == "")break;
if (s_che[i] == d_che[j])
{
mark = mark + 1;
}
}
}
mark = mark * 4;
return mark;
}
int cmpoint(float p1, float p2)
{
int mark = 0;
if (p1 >= p2)
{
mark = mark + 10;
}
return mark;
}
int cmp(float point, string* schedual, string* interests, float point1, string* schedual1, string* interests1)
{
int mark;
mark = cminterests(interests, interests1) + cmschedual(schedual, schedual1) + cmpoint(point, point1);
return mark;
}
5、运行及测试结果展示
- 测试200位同学,20个部门的情况
输入数据
完整数据点此
{
"department": [
{
"Department_No": "D087",
"Department_Name": "H867",
"Limit": 3,
"GPA_Limit": 1.1069999933242798,
"Tags": [
"programing",
"basketball",
"film",
"dancing",
"running"
],
"Schedules": [
"Sat.9: 00~10: 00",
"Fri.13: 00~14: 00",
"Wed.13: 00~14: 00",
"Tue.19: 00~20: 00",
"Wed.9: 00~10: 00"
]
},
...
"student": [
{
"Student_No": "S031500435",
"Student_Name": "B107",
"Sex": "male",
"GPA": 4.166130065917969,
"Tags": [
"running",
"travelling",
"swimming"
],
"Free_Time": [
"Thu.9: 00~10: 00",
"Mon.10: 00~11: 00",
"Sat.16: 00~17: 00"
],
"Choice": [
"D087",
"D042"
]
},
...
}
输出数据
完整数据点此
{
"matched_department_view": [
{
"department_no": "D010",
"chosen_students": ["S031507426","S031504905"]
},
...
"matched_student_view": [
...
{
"department_no": "S031507426",
"chosen_department": ["D010","D086","D075"]
},
...
"standalone_departments": [
"D004",
"D034"
],
"standalone_students": [
"S031507932","S031500103","S031504247",
...
}
- 测试500位同学,30个部门的情况
输入数据
完整数据点此
{
"department": [
{
"Department_No": "D042",
"Department_Name": "S141",
"Limit": 1,
"GPA_Limit": 1.8980000019073487,
"Tags": ["film","math","sports","swimming","travelling"],
...
"student": [
...
{
"Student_No": "S031502129",
"Student_Name": "H840",
"Sex": "female",
"GPA": 4.138800144195557,
"Tags": [
"math",
"music"
],
"Free_Time": [
"Mon.9: 00~10: 00","Thu.15: 00~16: 00","Wed.10:
00~11: 00","Fri.19: 00~20: 00","Sun.20: 00~21: 00","Fri.21: 00~22: 00","Thu.10: 00~11: 00","Sat.19: 00~20: 00","Tue.14: 00~15: 00","Fri.13: 00~14: 00"],
"Choice": ["D041","D031"]
}
]
}
输出数据
完整数据点此
{
"matched_department_view": [
{
"department_no": "D042",
"chosen_students": [
"S031505929"
]
},
...
]
"matched_student_view": [
{
"department_no": "S031504618",
"chosen_department": [
"D048"
]
},
...
]
"standalone_departments": [
"D057",
"D031",
"D040",
"D070",
"D058"
],
"standalone_students": [
"S031506502",
"S031502946",
"S031507815",
"S031507228",
...
]
}
- 测试1000位同学,50个部门的情况
输入数据
完整数据点此
{
"department": [
{
"Department_No": "D066",
"Department_Name": "X990",
"Limit": 3,
"GPA_Limit": 2.5360000133514406,
"Tags": [
"hiking",
"dancing",
"English",
"swimming",
"reading"
],
...
"student":[
...
{
"Student_No": "S031504847",
"Student_Name": "W893",
"Sex": "male",
"GPA": 3.1907501220703127,
"Tags": [
"game",
"music"
],
"Free_Time": [
"Sat.9: 00~10: 00","Sat.14: 00~15:00","Mon.9: 00~10:00","Tue.20: 00~21: 00","Sun.20:00~21: 00","Sat.21: 00~22: 00","Tue.10: 00~11: 00","Sat.10: 00~11: 00"],
"Choice": [
"D078",
"D091",
"D041"
]
},
...
]
}
输出数据
完整数据点此
{
"matched_department_view": [
{
"department_no": "D066",
"chosen_students": [
"S031500428",
"S031505147",
"S031501728"
]
},
...
]
"matched_student_view": [
{
"department_no": "S031501327",
"chosen_department": [
"D098",
"D037"
]
},
...
]
"standalone_departments": [
"D075",
"D056",
"D093",
"D038"
],
"standalone_students": [
"S031508339",
"S031501654",
"S031503336",
...
]
}
- 测试5000位同学,100个部门的情况
输入数据
完整数据点此
{
"department": [
{
"Department_No": "D066",
"Department_Name": "A948",
"Limit": 14,
"GPA_Limit": 1.600000023841858,
"Tags": [
"music",
"document",
"travelling",
"programing",
"game"
],
"Schedules": [
"Mon.14: 00~15: 00",
"Mon.21: 00~22: 00",
"Thu.14: 00~15: 00",
"Sun.10: 00~11: 00",
"Tue.14: 00~15: 00"
]
},
...
]
"student": [
{
"Student_No": "S031504233",
"Student_Name": "M553",
"Sex": "male",
"GPA": 3.126610040664673,
"Tags": [
"dancing",
"running"
],
"Free_Time": [
"Wed.9: 00~10: 00",
"Wed.10: 00~11: 00",
"Tue.9: 00~10: 00",
"Fri.16: 00~17: 00",
"Thu.16: 00~17: 00",
"Wed.19: 00~20: 00",
"Thu.14: 00~15: 00",
"Fri.19: 00~20: 00",
"Mon.10: 00~11: 00"
],
"Choice": [
"D053",
"D056",
"D075",
"D026"
]
},
...
]
}
输出数据
完整数据点此
{
"matched_department_view": [
{
"department_no": "D066",
"chosen_students": [
"S031500428",
"S031505147",
"S031501728"
]
},
...
]
"matched_student_view": [
{
"department_no": "S031500428",
"chosen_department": [
"D066",
"D090"
]
},
...
]
"standalone_departments": [
"D075",
"D056",
"D093",
"D038"
],
"standalone_students": [
"S031508339",
"S031501654",
"S031503336",
...
]
}
- 效能分析报告
测试数据(100,5000)
在此前读json花费了巨大时间(超过一分钟),后来改进读取方式耗时不到四秒,主要耗时在matching匹配函数,另外读取json占一部分。
5、遇到的困难及解决方法
-
困难描述
1.对于采用c++读取和写入json文件完全陌生。
2.每次操作部门都需要遍历所有学生,导致性能不佳。
-
做过哪些尝试
1.在网络上寻找有效的解决方案和相关代码。
2.寻求队友的帮助。
-
是否解决
采用较为流行的腾讯开源库rapidjson来读取和写入json,至少解决了输入输出问题。
匹配算法性能目前还处于较差的阶段,5000-100运行超过一分钟(汗颜)
-
有何收获
get到json的相关姿势
6、对队友的评价
-
有哪些好的地方值得学习
编码效率高,沟通能力良好!给五星好评,下次我再来。
-
有哪些不好或者需要改进的地方
代码风格太过随意,函数和变量命名往往都看不懂还需他解释(可能我水平太菜了吧),缺少注释。
7、PSP
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
· Estimate | · 估计这个任务需要多少时间 | 60 | 60 |
Development | 开发 | 1330 | 1430 |
· Analysis | · 需求分析 (包括学习新技术) | 120 | 60 |
· Design Spec | · 生成设计文档 | 100 | 60 |
· Design Review | · 设计复审 (和同事审核设计文档) | 60 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 100 | 0 |
· Design | · 具体设计 | 100 | 100 |
· Coding | · 具体编码 | 650 | 800 |
· Code Review | · 代码复审 | 100 | 150 |
· Test | · 测试(自我测试,修改代码,提交修改) | 100 | 150 |
Reporting | 报告 | 150 | 250 |
· Test Report | · 测试报告 | 135 | 100 |
· Size Measurement | · 计算工作量 | 30 | 25 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 10 |
合计 | 1450 | 1625 |
8、学习进度表
1、结队信息
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 300 | 300 | 6 | 6 | 重拾C++,初学PHP |
2 | 15 | 21 | 学习了原型设计软件的操作及NABCD概念 | ||
3 | 600 | 900 | 24 | 45 | 学习json的读写,C++ level up |