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

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

031402337 胡心颖
031402341 王婷婷


作业概述

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

作业要求

  • 输入的数据,另外写生成程序随机实现。
  • 为输入输出设计标准化、通用化、可扩展的接口,为该智能匹配程序模块后期可能的整合入系统提供便利。
  • 输入输出的格式,如采用文本文件或数据库的方式输入,可自由讨论确定,但需要明确,为后期可能的整合入系统提供便利。
  • 需要为智能匹配算法确立几条分配或排序原则,比如 绩点优先、或其他、或其他等等,请你们结对讨论确定。
  • 算法评价的目标是:对于同一组输入,输出的未被导师选中的学生数越少越好。
  • 代码具有规范性。
  • 实现的程序语言不做限制性要求。
  • 代码提交在https://coding.net 上。
  • 两个人共同撰写一个博客,包含上述内容的描述,同时包含结对感受,以及两个人对彼此结对中的闪光点或建议的分享。

作业分析

算法思想为采用 贪心思想 ;
简单来说,首先将学生按照绩点从高到低排序,优先分配绩点高的学生;
然后针对每个学生,首先过滤掉其重复选择的导师,然后按照权重值 teacher[i].qz (后面介绍)高低来分配导师,权重值相同的情况下按照学生志愿排序;
teacher[i]表编号为i的导师,teacher[i].left表示该导师剩余学生数,teacher[i].want表示选择了该导师的学生总数,teacher[i].qz表示teacher[i]导师对于该学生的权重值(在本算法中可认为是匹配程度,越大越匹配)

teacher[i].qz =teacher[i].left/teacher[i].want

对于每个学生的五个志愿导师,都计算出其对应的权重值,按照权重值高的分配,如果有多个权重值相同,那么则按照志愿顺序分配;
从权重值计算公式可以看出,teacher[i].left越大,teacher[i].want越少,代表导师剩余数越多和导师越冷门来分配,在符合学生志愿的情况下,使得大多数学生都能分配到导师;
权重值相同时按照志愿顺序来分配,使得学生都能选择到自己较喜爱的导师

流程图

代码分析

基本数据结构

struct Student // 学生结构体
{
	int num;//学生编号
	double grade;//学生绩点
	bool flag;//是否分配了导师
	int tea[10];//志愿
}stu[110];
struct Teacher //老师结构体
{
	int num;//导师编号
	double need;//可以接受的学生数
	double left;//还剩下的名额
	double want;//被几个学生选择
	double qz;//权重,qz=left/need
	bool flag;//是否有学生
	vector<int> stu;//接受的学生
}teacher[50];···

产生随机数据

srand(time(0));
	for(int i=0;i<30;i++)//导师随机数据
	{
		int want;
		want=rand()%9;
		fprintf(f,"%d %d
",i,want);
	}
	for(int i=0;i<100;i++)//学生随机数据
	{
		int g=rand()%500;
		if(g<=100)g+=100;
		double grade=(double)g/100.0;
		fprintf(f,"%d %lf %d %d %d %d %d
",i,grade,rand()%30,rand()%30,rand()%30,rand()%30,rand()%30);
	}

使用srand()函数创造随机数;
导师随机生成想要的学生个数,将随机数模9,使得数据范围在 0-8 之间;
学生随机生成绩点以及想要的导师编号,绩点控制在1-5之间,导师编号在0-29之间

权重值teacher[i].qz

for(int i=0;i<30;i++)//计算导师权重
	{
		teacher[i].left=teacher[i].need;
		if(teacher[i].want==0)teacher[i].qz=-1;
		else teacher[i].qz=teacher[i].left/teacher[i].want;
	}

teacher[i]表编号为i的导师,teacher[i].left表示该导师剩余学生数,teacher[i].want表示选择了该导师的学生总数;
如果导师想要的学生数为0 ,则直接将teacher[i].qz(权重值)设为-1,
否则权重值teacher[i].qz=teacher[i].left/teacher[i].want

绩点排序函数

bool cmp(Student a,Student b)//学生按照绩点的高到低排序
{
	return a.grade>b.grade;
}

将学生按照绩点的高到低排序

导师分配函数

sort(stu,stu+100,cmp);//学生排序
	for(int i=0;i<100;i++)
	{
		double now;
		int ans;
		now=0;
		ans=-1;
		for(int j=0;j<5;j++)
		{
			if(now<teacher[stu[i].tea[j]].qz)/到志愿导师中权重最高的导师
			{
				now=teacher[stu[i].tea[j]].qz;
				ans=stu[i].tea[j];
			}
		}
		if(ans==-1)continue;//如果找不到符合要求的导师就下一个
		teacher[ans].stu.push_back(i);//修改导师的剩余名额以及其他信息
		teacher[ans].left--;
		teacher[ans].want--;
		teacher[ans].qz=teacher[ans].left/teacher[ans].want;
		if(teacher[ans].flag==0)
		{
			countt--;
			teacher[ans].flag=1;
		}
		stu[i].flag=1;//修改学生的信息
		counts--;
	}

先将学生按照绩点初步排序,在通过权重值和志愿顺序来分配

程序运行结果

生成随机数据样例

使用srand()函数创造随机数;
导师编号从0至29,后面紧跟导师想要的学生数从0到8
学生编号从0至99,后面紧跟其绩点 从1.00到5.00,再接着就是五个志愿导师
https://coding.net/u/songyufeng/p/DSFPXT/git/blob/master/data.txt

匹配结果样例

经过匹配之后的结果:
首先输出没有匹配的导师以及没有匹配的学生,
紧接着按照导师序号来输出每个导师的匹配学生情况
https://coding.net/u/songyufeng/p/DSFPXT/git/blob/master/ans.txt

算法效率评估、闪光点、改进方向

效率评估

  • 以下是10次随机试验的学生分配情况结果
  • 从图表中数据来看几乎所有学生都能够分配到导师,近乎完美,不得不感叹过贪心算法真的超级棒啊!
  • 那么学生的志愿情况呢,是每个学生都能分配到其志愿靠前的导师?
  • 以下是10次随机试验的学生志愿平均情况(只计算了有被分配到的学生)
  • 从图表中可以看出 第一志愿人数>第二志愿>第四志愿>第三志愿>第五志愿
  • 根据我们先前的优先分配绩点高的同学的思想,想必绩点高的同学所分配的志愿自然是比较靠前的,下面我们也验证一下这一点
  • 按照绩点段来查看志愿情况
  • 由于绩点是随机生成的,所以各个绩点段的人数相同(这也是我们考虑不周到、比较不科学的地方,因为现实生活中绩点不可能平均分配)
  • 绩点为 [4.00 - 5.00 )的绩点大神
  • 绩点为 [3.00 - 4.00 )的学霸
  • 绩点为 [2.00 - 3.00 )的伪学霸
  • 绩点为 [1.00 - 2.00 )的学渣吧
  • 图标完美验证了按照绩点优先分配的情况

闪光点

  • 算法的思想 - 贪心思想
  • 对于某个学生重复选择某位导师的情况,系统能够过滤掉
  • 能够保证 最广大学生 分配到自己志愿的导师的情况,又可满足 绩点高者优先分配 以及尽可能 分配志愿靠前的导师

改进方向

  • 学生绩点生成得不够合理,不够满足现实情况,影响了后面的志愿情况分析

作业感想

  • 宋御风:结对编程比一个人编程感觉更加集中,在第二次结对编程作业,构思分配算法的时候,一个人很容易导致思维僵化,两个人探讨,听取对方的意见,效率会快很多。一个人编程经常完成一个模块的内容就想休息,两个人在一起会强迫自己做下去。而且如果两个人的思维和知识面互补的话,对项目各方面的完善都很有助益。
  • wangtingting007:结对编程有助于克服拖延症,摆脱懒癌患者的毛病,同时结对过程能够与队友好好沟通、交流想法等,真的是一件很棒的事!然后结对过程能够结合两个人的特长和不足合理分工、提高作业效率和质量!队友代码能力好强!!!!

作业链接:https://coding.net/u/songyufeng/p/DSFPXT/git
项目说明:README.md
分配导师:a.cpp

原文地址:https://www.cnblogs.com/wangtingting007/p/5916489.html