zoukankan      html  css  js  c++  java
  • 第二次结对编程作业——毕设导师智能匹配

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

    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

  • 相关阅读:
    Window 窗口类
    使用 Bolt 实现 GridView 表格控件
    lua的table库
    Windows编程总结之 DLL
    lua 打印 table 拷贝table
    使用 xlue 实现简单 listbox 控件
    使用 xlue 实现 tips
    extern “C”
    COleVariant如何转换为int double string cstring
    原来WIN32 API也有GetOpenFileName函数
  • 原文地址:https://www.cnblogs.com/songyufeng/p/5917344.html
Copyright © 2011-2022 走看看