第二次结对编程作业——毕业导师智能匹配

结对编程人员

031402418汪培侨 031402618林宇晨

一、问题描述

编码实现一个毕设导师的智能匹配的程序。提供输入包括:30个老师(包含带学生数的要求的上限,单个数值,在[0,8]内),100个学生(包含绩点信息),每个学生有5个导师志愿(志愿的导师可以重复但不能空缺)。实现一个智能自动分配算法,根据输入信息,输出导师和学生间的匹配信息(一个学生只能有一个确认导师,一个导师可以带少于等于其要求的学生数的学生)
及 未被分配到学生的导师 和 未被导师选中的学生。

二、问题分析

经过商讨后得出以下问题:

  • 数据输入要采用数据库还是txt?
  • 同学的中选要以绩点为优先、对某个老师的喜爱程度优先~~?
  • 同学的志愿里面里面如果填了多个同样的老师又该如何分配?
  • 到底要用什么语言?
  • 填了多个老师意味着他非常喜欢这个老师?
  • 随机生成的数据,是不是不太符合我们现实的情况?
  • 算法的目标没中选的学生人数越少越好?
  • 5个志愿到底是平行志愿,还是有先后顺序?

经过一番系列性的讨论,以及两次攥写的经过,可以得出我们小组的答案

  • 编程语言:C/C++
  • 数据输入输出:采用文本TXT的形式
  • 随机生成数据:对随机生成数据的概率进行了一定的约束,模拟较为现实的环境
  • 志愿顺序的关系:和志愿的排序有一定的关系,每一个次序所占权重不同,但相差不会太大
  • 分配规则:对学生的绩点,以及对某某老师的喜爱程度(多志愿选择同一老师)进行一定权重的积,绩点所占比重会大一点
  • 算法目标:让更多的选手选到自己志愿里面的老师,权重高的中选的自己喜欢的老师的机会大

接下来将我们实现的算法进行解释说明。

三、算法的实现策略

1、数据的生成

为了更好的贴切现实生活中,学生选择老师的情况,我们对随机的生成数据进行了一定的约束,以便于后续的模拟。

教师大体可以分为这三类:

  1. 热门老师
  2. 普通老师
  3. 冷门老师

我们的模拟数据生成器中,就选择了6个热门老师,14个普通热门老师,10个普通老师

以上为对应单个老师的被学生选中的概率分析图。

我们将学生选择志愿的老师的程度用上图描述。

教师数据生成

   for(i=0;i<m;i++)    //教师工号的生成,按tea0-29 ,以及对应的要选择学生的人数{if(i>=0 && i <=9)   fprintf(fpWrite,"tea00%d\n", i);else if(i>9)  fprintf(fpWrite,"tea0%d\n", i);fprintf(fpWrite,"%d\n",rand()%8+1);}  

学生数据生成

   for(j=0;j<n;j++)    //学生学号,基点,五个志愿对应老师的选择 {    if(j==0) fprintf(fpWrite,"stu000\n");              //学号 else if(j>0&&j<=9) fprintf(fpWrite,"stu00%d\n",j);  else if(j>9) fprintf(fpWrite,"stu0%d\n",j);double jidian;jidian = ( rand()%101 ) /25.0 + 1;fprintf(fpWrite,"%.1lf\n",jidian);         //绩点 /*模拟对应志愿的选择,每个志愿的对应的老师的概率不同*/ for (i=0; i<5; i++){number = rand() % 150;if(number<60) number=number%30;else if(number>=60&&number<100){number=(number-59)%6;   }else if(number>=100){number=(number-99)%20;} if(number>=0 && number <=9)    fprintf(fpWrite,"tea00%d\n", number);else if(number>9)  fprintf(fpWrite,"tea0%d\n", number);}}

实现代码可参见

https://coding.net/u/peiqiaoWang/p/work_num2/git 里面的rand_1.cpp

2、权重的计算

绩点权重

基点权重的计算:分为4个阶级用以下图表示

上图为各个阶级段的绩点所占权重,该值为多次实验反复修改后得到的值,

设分权重为Q1,则
$$
Q1=绩点*上述对应的绩点权重
$$
对应代码

int jdqz(double jidian)//计算绩点权重
{int qz;if(jidian<2 && jidian>=1) qz=100;else if(jidian<3 && jidian>=2) qz=120;else if(jidian<4 && jidian>=3) qz=130;else if(jidian<=5 && jidian>=4) qz=140;return (int)qz*jidian;
};

教师权重

教师权重表示的是XX学生的XX老师的喜爱程度

每一个志愿的老师对应权重

如果选择多个志愿选择同样的老师,那就以第一个志愿的权重为基准,加上后续选择的同样老师的志愿权重/5,此番设计也是通过多次实验,反复修改得到

设分权重(学生对XX老师)为Q2
$$
Q2=第一个出现该老师的权重+后续出现老师的权重/5
$$

总权重

设总权重为Q(stuxx,teaxx),以及上述的绩点权重Q1,教师权重Q2,可以得到某某学生对某某老师的总权重:
$$
Q(stuxx,teaxx)=Q1*Q2
$$
后续将会以这个权重Q会平衡点以及老师所需要的学生人数为基准去实现分配

3、学生分配

第一次算法模拟:

流程图如下

总结上述算法在实验中遇到的问题:

在模拟一般选志愿的时候还比较OK,就是选中30个老师,每个老师的概率都是一样的,后面换了测试数据后,发现这个算法会导致还有10多个学生没有中选老师,显然这是不可接受的。于是我们又找了第二个算法进行了尝试。

第二次算法模拟

在请教了同学之后,得到了一个偶然的算法,最小费用最大流(MCMF)算法!!!

下面介绍该算法

算法介绍:

在一个网络中每段路径都有“容量”和“费用”两个限制的条件下,此类问题的研究试图寻找出:流量从A到B,如何选择路径、分配经过路径的流量,可以达到所用的费用最小的要求。如n辆卡车要运送物品,从A地到B地。由于每条路段都有不同的路费要缴纳,每条路能容纳的车的数量有限制,最小费用最大流问题指如何分配卡车的出发路径可以达到费用最低,物品又能全部送到。

类比一下我们的题目:

  • 容量就相当于每一个学生只能选择一个老师,每一个老师收的学生都有上限一样,费用可以看成是学生对老师权重的大小,我们这里要权重最大的那个,因此要把权重做一定的处理,把大的权重通过一定的映射转化成题目所需的小权重。

如图所示:

这里的起点终点,与卡车题中的起点和终点一样,学生点和老师点就相当于走过的路径,最终就是为了,优先实现最大流基本上的路径都能经过(尽量让每个学生都能选上老师),然后在让费用最小(通过映射即让权重大的尽量走过)

模拟效果也比我们第一个算法有了很大的进步。

代码如下:

struct MCMF//最小费用最大流
{   int n,m,s,t;vector<Edge> edges;vector<int> G[N];int inq[N],d[N],p[N],a[N];void init(int n)//初始化 {this->n=n;for(int i=0; i<n; i++) G[i].clear();edges.clear();}void addedge(int from,int to,int cap,int cost)//连边 {edges.push_back(Edge(from,to,cap,0,cost));edges.push_back(Edge(to,from,0,0,-cost));int m=edges.size();G[from].push_back(m-2);G[to].push_back(m-1);}bool SPFA(int s,int t,int &flow,int &cost)//求最短增广路 {for(int i=0;i<n;i++) d[i]=INF;memset(inq,0,sizeof(inq));d[s]=0;inq[s]=1;p[s]=0;a[s]=INF;queue<int> Q;Q.push(s);while(!Q.empty()){int u=Q.front();Q.pop();  inq[u]--;for(int i=0;i<G[u].size();i++){Edge& e=edges[G[u][i]];if(e.cap>e.flow && d[e.to]>d[u]+e.cost){d[e.to]=d[u]+e.cost;p[e.to]=G[u][i];a[e.to]=min(a[u],e.cap-e.flow);if(!inq[e.to]){inq[e.to]++;Q.push(e.to);}}}}if(d[t]==INF) return false;flow+=a[t];cost+=d[t]*a[t];int u=t;while(u!=s){edges[p[u]].flow+=a[t];edges[p[u]^1].flow-=a[t];u=edges[p[u]].from;}return true;}int run(int s,int t)//运行 {int flow=0,cost=0;while(SPFA(s,t,flow,cost));return cost;}void PrintPlan(int l,int r)//输出方案 {int Plan[N];memset(Plan,0,sizeof(Plan));for(int i=0; i<edges.size(); ++i)if(edges[i].cap==edges[i].flow&&edges[i].cap&&edges[i].from>=l&&edges[i].from<=r)Plan[edges[i].from]=edges[i].to-r;for(int i=l; i<=r; ++i)if(Plan[i]) printf("学生学号 %s 所分配教师工号 %s\n",Sname[i],Tname[Plan[i]]);for(int i=l; i<=r; ++i)if(!Plan[i]) printf("学生学号 %s 未分配老师\n",Sname[i]);}
};

四、结对感受

031402418汪培侨

我觉得把结对,最重要的就是能让你写代码的时候更专注,而且互相分析问题会更加的全面,毕竟两个脑子,互相补充。这次的作业相比上一次应该是要难很多,但期间的收获还是蛮大的,比如第一次的算法就因为处理数据不够强,就被我们淘汰了,最终还是找到了一个MCMF算法,多亏同学帮忙。这次我要给我的队友满分,在我还在纠结要不要换算法增加工作量时,最终还是选择了换算法。继续加油。

031402618林宇晨

觉得这次结对的任务量比上次小了一些,但是觉得交流上的难度变大了,在讨论算法的时候两个人发生了较大的分歧,两人沟通不好,没有很好的表达出自己的意思,结果导致第一次采用的方法在引入6个导师后出现了较大问题,后来连夜修改了算法,用我的话说就是“命都没了半条”。关于git的使用方面,因为采用的是结对编程的方式,使用较少。最后总结下这次的作业,个人认为最突出的问题有两个,第一是交流较失败导致进度被拖下,第二点是设计算法的时候烤炉的不够周全导致实现的时候出现了种种问题。

闪光点:
1、能够根据实际的情况去模拟数据的生成
2、大砍一刀换算法的勇气
建议分享:
讲道理,上面大砍一刀的情况其实我们并不想看到,所以我觉得在做这个之前,还是去浏览一些相关的论文,以便于增多自己的可选择的方法,让自己的肚子更有墨水。

五、Coding.net上的代码

详情请戳这里,请看里面的README

https://coding.net/u/peiqiaoWang/p/work_num2/git

转载于:https://www.cnblogs.com/wpqwpq/p/5922118.html

第二次结对编程作业——毕业导师智能匹配相关推荐

  1. 第二次结对编程作业——毕设导师智能匹配

    鲍亮 031402401 李陈辉 031402409 问题描述: 编码实现一个毕设导师的智能匹配的程序.提供输入包括:30个老师(包含带学生数的要求的上限,单个数值,在[0,8]内),100个学生(包 ...

  2. 结对编程作业——毕设导师智能匹配

    结对编程作业--毕设导师智能匹配 031402317 李佳恺 031402511 黄家俊 问题描述及要求 输入30个老师(包含带学生数的要求的上限,单个数值,在[0,8]内),100个学生(包含绩点信 ...

  3. 学生和老师匹配java_结对编程作业——毕设导师智能匹配

    结对编程作业--毕设导师智能匹配 031402317 李佳恺 031402511 黄家俊 问题描述及要求 输入30个老师(包含带学生数的要求的上限,单个数值,在[0,8]内),100个学生(包含绩点信 ...

  4. 2022秋软工实践 第二次结对编程作业

    这个作业属于哪个课程 fzusdn 这个作业要求在哪里 作业要求 这个作业的目标 生成指定条件数据集,实现效益最大的点名策略 学号 032004110 队友学号 032004119 commit记录 ...

  5. 软件工程第五次作业——第二次结对编程

    题目要求 本次作业要求两个人合作完成,驾驶员和导航员角色自定,鼓励大家在工作期间角色随时互换,这里会布置两个题目,请各组成员根据自己的爱好任选一题. 题目1: 我们在刚开始上课的时候介绍过一个小学四则 ...

  6. 2021软工第一次结对编程作业

    这个作业属于哪个课程 构建之法-2021秋-福州大学软件工程 这个作业要求在哪里 2021秋软工实践第一次结对编程作业 这个作业的目标 结对完成任务并学会原型设计 学号 031902414 队友学号 ...

  7. 软件工程网络15结对编程作业

    软件工程网络15结对编程作业 1.项目成员 学号:201521123014 博客地址:http://www.cnblogs.com/huangsh/ 学号: 201521123102 博客地址:htt ...

  8. 2022秋软工实践 第一次结对编程作业

    2022秋软工实践 第一次结对编程作业 需求分析 (1)Need,需求 (2)Approach,做法 (3)Benfit,好处 (4)Competitors,竞争 (5)Delivery,推广 UML ...

  9. 2021秋软工实践第一次结对编程作业

    这个作业属于哪个课程 构建之法-2021秋-福州大学软件工程 这个作业要求在哪里 2021秋软工实践第一次结对编程作业 这个作业的目标 实现博饼软件原型并进行博客写作 学号 031902139 队友学 ...

  10. 2022软工K班结对编程作业

    逍遥骰GitHub链接 哔哩哔哩功能展示 学号 姓名 作业博客链接 具体分工 032002621 林灿彬 待填写 JavaScript编程.AI设计 032002623 林达锴 待填写 原型制作.ht ...

最新文章

  1. 外国人看我国量子计算机祖冲之号,1.2小时完成超算8年!我国“祖冲之号”量子计算机刷新记录...
  2. MySQL配置教程(图解版)
  3. python线程检测网段脚本!
  4. 验证哥德巴赫猜想:任何一个大于6的偶数均可表示为2个素数之和
  5. OSChina 周日乱弹 ——已经打码请放心观看
  6. Mr.J--贪吃蛇demo
  7. 数据科学的原理与技巧 二、数据生成
  8. 炼丹手册——NaN值问题
  9. Jpeg压缩的两种方法
  10. Abp框架 Abp中使用Redis
  11. 东野圭吾《沉默的巡游》简单书评(含剧透)
  12. VirtualBox虚拟机提示内存0x00000000不能为written问题
  13. C#-----集合ListT的常用方法
  14. 计算机碎片整理的作用,经常做磁盘碎片整理的好处
  15. 如何用Java打开PDF文件
  16. 根据股票涨跌用KMeans进行分类
  17. Cesium实现UnrealBloom泛光效果
  18. Unity中的半透明阴影
  19. 洛谷 1144 最短路计数 bfs
  20. 翻棋子游戏与Nim游戏

热门文章

  1. Memcached在Windows7上的安装问题
  2. 你可能不知道的CSS3属性: object-fit,object-position的妙用
  3. Win10网络连接面板中突然出现空白一片的解决办法
  4. 归并排序(链表结构)
  5. 微服务学习之Hystrix图形化DashBoard监控【Hoxton.SR1版】
  6. weblogic安装部署 linuxs——wls1036版本
  7. 关于oracle存储微信表情emoji问题 “[[%F0%9F%A4%AA]]“
  8. javassist组件分享利用javassist动态创建一个类
  9. jQuery动画:实现渐入渐出
  10. Excel的设置 .net