这是一个困扰我很久的问题,今天早上洗脸的时候突然想起,事实上也没有一开始想象中的那么困难,不管三七二十一、四七二十八,先记录下来再说。
要求:
1、学校在某个学期一共开放了N门课程由学生自由选择,每一个学生可以选择一门或几门课程进行学习。
2、在进行期末考试时,同一学生选修的两门课程不能安排在同一个时间考。
原本还想要求在最短时间内考完,但只要加上一个“最”字,实现起来就比较困难了,所以,先简化一下,只要同一学生选修的两门课程不能安排在同一时间内考试即可。
学生选课表(SelectCourse)的结构如下图所示:
其中:
Id:自动增长的主键
StudentId:学号
StudentName:姓名
CourseName:选课的课程名
考场安排表(Exam)的结构如下图所示:
其中:
Id:自动增长的主键
ExamScreenings:考场场次,既第几场考试
Course:考试课程名
ExamNum:该门课程的选课人数
算法如下所示:
1、设置考场中最多可同时考试的人数。
2、统计每门课程的考试人数,放入临时表中。
3、先在临时表中选出选课人数最多的那门课程,当然,必须要先确定考场中最多可同时考试的人数要大于单门课程的最多选课人数。
4、将考试场次加1,并将选课人数最多的课程(当前课程)添加到考场安排表里(Exam),然后将该门课程从临时选课表中删除。
5、然后将考试最多可同时考试的人数减去已经安排的考试课程的人数,得到考场中还可以安排的考试人数,即剩余考试人数(@RemainNum)
6、选择所有选课人数少于或等于剩余考试人数的课程,并放到游标里。
7、循环从游标里取出课程,判断选择该课程的学生是否和当前考试场次中已安排的课程的选课学生有冲突(既是否同一学生在同一时间内参加两门考试)。如果没有冲突,则将该课程放入考场安排表中,并从临时表中删除该门课程。
8、重新统计剩余考试人数,返回到第5步骤,直到所有选课人数少于剩余考试人数,或着所有考试都有冲突不能安排为止。
9、返回第3步骤,直到所有课程都已经安排为止。
具体实现的SQL语句如下所示:
这个算法运行速度还可以,我试了13756人次131门选课,运行结果20秒左右。但是,这不是最优的算法,这131门的选课一共需要106个场次的考试,天哪,太多了!
可以说,这个算法失败了!
有人知道更好的算法吗?
原创不容易,转载请注明出处。http://blog.csdn.net/smallfools/archive/2009/12/08/4961307.aspx
相关文章: