问题描述
目标
实现一个毕业生导师智能分配的程序.
输入
老师:30人、老师要求选择的学生数:0~8
学生:100人、绩点、学生的五个志愿输出
根据输入的信息,输出选择的结果,要求一个学生只能有一个老师,一个老师可以有
0~8个学生,未分配的老师和学生。尽可能少的学生和老师未匹配。问题分析
第一次讨论的时候,我们打算将各种因素综合起来,合并成老师-学生相互选择的一个权重
然后进行分配,这时候就遇到了下面的问题。影响选择的因素有学生的绩点,志愿,老师的 意愿。在多因素下如何分配各个因素的权重?这个问题讨论了很久,建一个数学模型?有点 困难?各因素乘上一个比例系数,比例系数该如何确定?人为确定吗?如何保证客观公正合理 ?匹配一般都是对两个对象建立联系并赋予一定的权值,来体现关系的优先。那么又回到上 面的问题。回过头将导师分配的流程走一遍发现,其实我们不用考虑这样问题。 在流程图中,老师同意学生的选择,对老师来说,不管学生绩点的高低,都是他想要的学生, 所以从老师的角度看,不用管这些学生的先后顺序。但从学生的角度看,绩点某种程度上体现 这个学生那么多个学期的努力。故按绩点将所有学生排序,将绩点高的学生优先分配,然后再 按志愿顺序分配还有名额的老师。执行三轮分配,若还有学生没有选到老师则进行人工干预。 (不过这个概率很低)。
编码环境
Visual Studio 2015
MySql Navicat For MySql 语言:C#、SQL
代码分析
主函数
static void Main(string[] args) { int ResultCount =0; //结果个数 int StudentCount =100; //学生个数 int TeacherCount = 30; //教师个数 DeleteData(); //清空数据 Console.WriteLine("清空数据成功"); RandomStudent(StudentCount); //随机生成学生 Console.WriteLine("随机学生成功"); RandomTeacher(TeacherCount); //随机生成教师 Console.WriteLine("随机教师成功"); Console.ReadLine(); //第一轮选择 StudentChoice("choice"); Console.WriteLine("第一轮学生选导师成功"); TeacherChoice("choice"); Console.WriteLine("第一轮导师选学生成功"); Console.ReadLine(); //第二轮选择 ResultCount = MySqlReadReturnCount("SELECT * FROM result");//获取结果个数 //判断所有学生是否都已经分配完毕 if (ResultCount < StudentCount) { StudentChoice("secondchoice"); Console.WriteLine("第二轮学生选导师成功"); TeacherChoice("secondchoice"); Console.WriteLine("第二轮导师选学生成功"); } else { Console.WriteLine("选择导师完毕"); } Console.ReadLine(); ResultCount = MySqlReadReturnCount("SELECT * FROM result");//获取结果个数 //判断所有学生是否都已经分配完毕 if (ResultCount < StudentCount) { StudentChoice("thirdchoice"); Console.WriteLine("第三轮学生选导师成功"); TeacherChoice("thirdchoice"); Console.WriteLine("第三轮导师选学生成功"); } else { Console.WriteLine("选择导师完毕"); } Console.ReadLine(); }
主要函数分析
随机数的生成
private static void RandomTeacher(int TeacherNumber)//随机生成老师 { string InsertString; string TmpID; string TmpStudentCount; try { for (int i = 0; i < TeacherNumber; i++) { TmpStudentCount = NewStudentCount();//随机生成预选学生数 TmpID = NewID();//根据时间随机生成ID InsertString = "INSERT INTO teacher(TeacherID,StudentCount,ChoiceStudentCount) VALUE('" + TmpID + "','" + TmpStudentCount + "', '0' )"; MySqlWrite(InsertString); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } private static void RandomStudent(int StudentNumber)//随机生成学生 { string InsertString; string TmpID; string TmpGPA; try { for (int i = 0; i < StudentNumber; i++) { TmpGPA = NewGPA();//随机生成绩点 TmpID = NewID();//随机生成ID InsertString = "INSERT INTO student(StudentID,GPA,IsSelect) VALUE('" + TmpID + "','" + TmpGPA + "', '0' )"; MySqlWrite(InsertString); } } catch(Exception e) { Console.WriteLine(e.ToString()); } }
模拟师生互选函数
private static void StudentChoice(string TableName)//模拟学生选择导师 TableName为进行分配操作的表名 { //string SelectString = "select * from teacher order by rand() limit 5"; string SelectTeacherString = "SELECT * FROM teacher WHERE StudentCount != ChoiceStudentCount"; string SelectStudentString = "SELECT * FROM student WHERE IsSelect ="+0; int Count = MySqlReadReturnCount(SelectTeacherString);//还未选满的老师个数 Console.WriteLine(Count); int StudentCount = MySqlReadReturnCount(SelectStudentString);//还未选中学生的个数 string[] TeacherID = new string[5]; string TmpID; string[] StudentID = MySqlReadArray(SelectStudentString, "StudentID");//获取还未被选中的学生ID //每个学生选5个志愿 for(int i = 0;iTmpChoiceStudentCount)//若老师人数未满 { //Console.WriteLine(StudentID[i]); MySqlWrite("INSERT INTO result(StudentID,TeacherID) VALUE('" + StudentID[i] + "','" + TmpTeacherID[j] + "')");//更新结果表 MySqlWrite("UPDATE student SET IsSelect = 1 WHERE StudentID = '" + StudentID[i] + "'");//更新学生数据为已被选中 AllResultCount++;//所有结果条数 TmpChoiceStudentCount++;/老师已选学生数++ MySqlWrite("UPDATE teacher SET ChoiceStudentCount =" + TmpChoiceStudentCount + " WHERE TeacherID ='" + TmpTeacherID[j] + "'");//更新老师数据已选人数 Console.WriteLine(AllResultCount+"学生" + StudentID[i] + "分配成功"); break;/选中老师跳出循环,对下个学生进行分配 } } } } }
其他函数
结果分析
生成数据
student表
teacher表 控制台界面第一轮选择
模拟学生选择导师
控制台界面 choice表(志愿表)100个学生 每个学生5个志愿 总共有500条记录
因为初始志愿导师还没有选择所以IsSelect都为0模拟导师选择学生
控制台界面 choice表IsSelect纪录该导师是否选择了该学生
result表: student表 IsSelect纪录学生是否中选重复轮数
小结&感想
王凌杰
本次结对编程我学会了git的基本使用,同时也对毕设导师匹配系统有了更为深刻的理解和思考。
本来我们也想像其他组那样用算法全自动匹配,然而考虑到很多数学建模的问题,而且感觉有很 多不符合实际的假设。于是我们决定实现模拟人为选择,再设计匹配方式进行匹配。我们匹配思 路主要在模拟导师选择学生之后,即实现按学生绩点来作为学生进行匹配的顺序的依据,而把志 愿顺序作为单个学生匹配不同志愿导师的顺序依据。 除了匹配,本次让我印象深刻的实现随机不重复的从数据库中调出数据。原本打算用"select * from teacher order by rand() limit 5"直接在数据库中实现,但效率出奇的低,于是便参考了 一些算法,由于时间较赶最后决定用比较Low的list.contain 来判断。李烈争
学会Git的基本使用,感谢助教推荐的Git博客,很详细。看学长的博客感叹markdown还可以那样用。
各种锚点。可以,很强!感谢队友的大腿,编码过程中耐心的讲解,我代码的能力有待提高。考虑的 过程中思维不够严谨,遗漏一些重要的点,拖了进度。两个人交流的时候要组织好后表达,可以提高 效率。