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


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

    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

  • 相关阅读:
    递归寻找子节点的所有父节点(父,爷,祖等)
    nodemon在VSCODE中 调试nodeJS的使用方法
    JavaBean转Map工具类
    command line is too long. shorten command line for xxx的解决方法
    Stream流中collect方法
    vue组件传值的方法有哪些
    Collectors.toMap 使用技巧 (List 转 Map超方便)
    Vue formcreate的基本使用
    报错:Unable to load authentication plugin ‘caching_sha2_password‘.
    ElementUi中eltable分页效果,前端控制分页
  • 原文地址:https://www.cnblogs.com/songyufeng/p/5917344.html
Copyright © 2020-2023  润新知