结对作业第二次
前言
错过了就是错过了,我也不想过多借口。不过我现在补上了。
一、结对成员
因为是后期补上的所以就我一人。
二、代码
三、问题描述
编码实现一个部门与学生的智能匹配的程序。
提供输入包括:20个部门(包含各部门需要学生数的要求的上限,单个,数值,在[0,15]内;各部门的特点标签,多个,字符;各部门的常规活动时间段,多个,字符/日期),300个学生(包含绩点信息,单个,数值;兴趣标签,多个,字符),每个学生有不多于5个的部门意愿(部门意愿不能空缺)和空闲时间段(多个,字符/日期)。实现一个智能自动分配算法,根据输入信息,输出部门和学生间的匹配信息(一个学生可以确认多个他所申请的部门,一个部门可以分配少于等于其要求的学生数的学生) 及 未被分配到学生的部门 和 未被部门选中的学生。 |
四、问题分析
|
五、 流程草图
流程图说明
1.学生权重计算:(志愿总数5-已加入部门数)*系数+绩点
2.初始数据随机生成:采用随机数,绩点为随机数mod 500,再缩小百倍,不过考虑到绩点必定>=1,以分布情况,选择把生成的<2的绩点自动加1,相对比较接近现状(大部分存在2-3之间)
六、实现过程
随机生成
for(int i=0;i<20;i++) { int want; want=rand()%15; fprintf(f,"%d %d\n",i,want); } for(int i=0;i<300;i++) { int g=rand()%500; if(g<=200)g+=100;//绩点基本集中2-3 double grade=(double)g/100.0; fprintf(f,"%d %lf %d %d %d %d %d\n",i,grade,rand()%20,rand()%20,rand()%20,rand()%20,rand()%20);//5个志愿 }
智能匹配
for(int zy=0;zy<5;zy++){//按照学生志愿,志愿优先 for(int i=0;i<300;i++)//计算学生权重 { stu[i].qz=(5-stu[i].flag)*10+stu[i].grade; } sort(stu,stu+300,cmp);//学生按权重排序 for(int i=0;i<300;i++) { if(department[stu[i].dep[zy]].left>0){//有空 int jsyet=0; for(int js=0;js<stu[i].depart.size();js++){//已经接收否 if(stu[i].dep[zy]==stu[i].depart[js]){ jsyet=1; break; } } if(jsyet==0){ stu[i].depart.push_back(stu[i].dep[zy]);//添加学生录取的部门 stu[i].flag++;//更新录取数 department[stu[i].dep[zy]].stu.push_back(i);//添加部门接收的学生 department[stu[i].dep[zy]].left--;//减少剩余名额 } } } }
智能匹配算法
优点:志愿的重要性,任何人的第一志愿都比其他人的第二志愿来的贵重,保证大部分人能分配到部门 缺点:导致少数绩点好的学生,因志愿选择问题出现无法加入。
优点:能够较为合理分配部门,使得已经加入的权重下降,加入少的甚至未加入的权重上升。 缺点:权重参数系数的选择尤为重要,选择失误,效果可能不好
优点:能较为简单快速寻找出局部最优。 缺点:这导致志愿的选择以及位置尤为重要。 |
总体总结&自我评价
基本的方法是有了,但是感觉部门的标签和空余时间未能很好的利用(这部分是个人能力以及时间问题),后期可以添加新的智能算法改进。 |
福大的凌晨四点我又要见到了,呵呵!