我目前正在编写一个将学生映射到课程的程序。目前,我正在使用SAT-Solver,但我正在尝试实现多项式时间/非贪心算法,该算法解决了以下子问题:
- 有学生(50-150)
- 有受试者(10-20),例如'数学','生物','艺术'
- 每个科目(至少一个)有课程,例如'math-1','math-2','biology-1','art-1','art-2','art-3'
- 学生选择一些(固定的)科目(10-12),并且对于每个科目,学生必须被分配到现有的一门课程(如果可能的话)。选择哪个课程'math-1'或'math-2'并不重要。
- 课程允许的学生人数最多(20-34)
- 每个课程都在一个固定的区块(=时间段1到13)
- 学生可能不会被分配到同一区块的课程
我现在正在描述到目前为止我所做的事情。
(1)忽略课程 - 学生限制
我能够用匈牙利算法/二分匹配来解决这个问题。每个学生可以通过如下建模来单独计算:
- 左节点代表主题'数学','生物','艺术'(学生)
- 右节点表示块'1','2',....'13'
- 从'subject'到'block'
为每个课程插入一条边
通过这种方式,学生被分配到课程的每个科目,而不是参加同一区块的课程。 但课程限制被忽略。
(2)忽略学生的选定科目
我能够用max-flow-algorithm解决这个问题。对于每个学生,建模如下:
- 第1层:从源到每个学生,流程为13
- 第2层:从每个学生到他/她的个人区块,流程为1
- 第3层:从每个学生区块到该区块中每个课程的流程1
- 第4层:使用'max-student-limit'
从每个球场到水槽
这样学生可以选择任意课程,并且课程限制已满。 但他/她可能不走运并被分配到'数学-1','数学-2'和'数学3'而无视主题'生物'和'艺术'。
(3)贪婪的匈牙利人
我的另一个想法是一次将一名学生与匈牙利算法匹配并调整权重,以便“更多空课程”成为首选。例如,可以建模:
- 左侧节点是学生的主题
- 右节点是块
- 为每个课程插入一个从主题到课程区块的边缘,重量=空位数
然后计算最大权重匹配。
我真的很感激任何建议/帮助。
谢谢!