第二次结队作业
结对成员: 031502641-郑珍发 **031502513-黄逸飞 **
2.https://github.com/emperor-fa/matching
3.贴出你们生成的一组最“好”的数据(给出对应链接即可),并详细说明"数据生成"程序的原理以及你们所考虑的因素。
https://github.com/emperor-fa/matching/blob/master/project/produce/input.txt
以学生的freetime为例,我们首先生成一个7到18的随机数(学生freetime的个数限制)在定义一个78的数组用来存放七个星期数和一天八个时间段,为了不重复定义一个56大小的数组,存放之前78的数组的序号选取一个序号,确认星期与时间,并在56中删除该序号,并重新选取。以类似方法确定部门志愿和兴趣标签的个数与内容,学号以累加1顺序生成
代码
void Student::create(string x) {
vector
vector
vector
stuInitialization(stutimeno, tagno, departno);
vector<int>freetemp; //创建一个数组用于存储时间下标,以便排序
freetemp.clear();
int freeno = rand() % 12 + 7;
for (int i = 0; i < freeno; i++) {
int timeindex = rand() % stutimeno.size(); //生成1-56随机序号
freetemp.push_back(timeindex);
stutimeno.erase(stutimeno.begin() + timeindex); //删除
}
sort(freetemp.begin(), freetemp.end()); //排序
for (int i = 0; i < freeno; i++) {
int x = stutimeno[freetemp[i]] / 8, y = stutimeno[freetemp[i]] % 8; //将随机数对应到二维数组下标
free_time.push_back(week[x] + to_string(stutime[x][y]) + ":00~" + to_string(stutime[x][y] + 2) + ":00"); //加入到学生空余时间
}
student_no = x; //学生学号
int studepartno = rand() % 5 + 1; //随机生成志愿部门的个数
for (int i = 0; i < studepartno; i++) {
int departindex = rand() % departno.size(); //随机生成下标
application_department.push_back(department[departindex]); //将随机下标对应的部门加入到志愿部门数组
departno.erase(departno.begin() + departindex); //删除该下标,防止重复
}
int stutagno = rand() % 3 + 2; //同上进行标签的生成
for (int i = 0; i < stutagno; i++) {
int tagindex = rand() % tagno.size();
tags.push_back(tag[tagindex]);
tagno.erase(tagno.begin() + tagindex);
}
}
4.详细说明你们数据建模及匹配程序的思路及实现方式。
读数据:按行读取,消除空格,以各行的信息,如student freetime等为判别数据属于哪个类,或是哪个类的哪个数组这部门是队友完成且讨论较少
匹配:按我们讨论,先按学生部门志愿从高到低依次加入部门若低的志愿与高的志愿活动时间发生冲突,则低志愿就不进行考虑(参考中高考志愿填报)待学生全部加入部门先看部门是否接收超过member limit如果超过,则学生按兴趣与部门相同个数,若相同一样,则按本身的兴趣标签个数排序择优录取
输出:先扫描学生,把学生的join为0的学号输出。再扫描部门,输出member中的学号
code
void sort(int j) { //部门成员根据标签相同个数,活动时间匹配个数进行排序
vector<int>sametag;
vector<int>sametime;
for (int i = 0; i < depart[j].member.size(); i++) { //记录标签相同个数,活动时间匹配个数
sametag.push_back(tag_same(depart[j].member[i], j));
sametime.push_back(time_same(depart[j].member[i], j));
}
for (int x = 0; x < depart[j].member.size()-1; x++) { //部门的成员排序
for (int y = x+1; y < depart[j].member.size(); y++) {
if (sametag[x] < sametag[y])
swap(sametag, sametime, x, y, j);
else if (sametag[x] == sametag[y]) {
if (sametime[x] < sametime[y])
swap(sametag, sametime, x, y, j);
void match() { //匹配
int i,j,k;
for (i = 0; i < 300; i++) { //学生
for (j = 0; j < stu[i].application_department.size(); j++) { //学生部门志愿j
if (j == 0) {
depart[atoi(stu[i].application_department[j].substr(3, 2).c_str()) - 1].member.push_back(i); //第一个志愿直接加入
stu[i].join++;
//cout << "ffgfbs";
}
else {
for (k = 0; k < j; k++) {
if (conflict[atoi(stu[i].application_department[k].substr(3, 2).c_str()) - 1][atoi(stu[i].application_department[j].substr(3, 2).c_str()) - 1] == 1) //如果该志愿与更高级志愿冲突,则不加入
break;
}
stu[i].join++;
5.你们在代码遵循了一定的规范,在博客中描述结对团队遵循的代码规范,并截取部分关键代码佐证说明。
代码规范,我们将头文件与源文件分开,头文件定义类和声明函数和全局变量,源文件又以功能的不同分成几个,类似读取、匹配、生成等cpp
6.结果评估。对于程序的匹配结果,你们是否满意?请对你们程序处理结果进行分析。
程序的匹配结果,我们还算满意。
结果是,未加入部门的学生为十几个,未收到人数的部门为0,部门招收人数不定但未超过限制人数。
7.已经尝试过结对编码,你一定很多话要说。请发表结对感受,以及两个人对彼此结对中的闪光点或建议的分享。
这是第二次结对作业,时逢国庆,没法两个在一起敲代码,对我们进行交流讨论造成了很大的麻烦,我们通过qq电话等工具进行交流和沟通,找出对方代码中自己不理解或对方错误,忽视的问题,但很大的矛盾在于自己描述不清楚,指出问题会被理解成另外的问题,而且彼此写代码风格都不一样水平也不一样,所以也造成了一定障碍。
但所幸的是队友的耐心和不辞辛苦,在遇到问题时的互相帮助,让我们顺利的完成这次做业。