小班课系统 - 运力匹配

288 阅读4分钟

一、背景

在线小班教育场景下如何控制运力一直是一个较难的事情;如果每次开班靠人力进行排班,排出的效果并不好,无法对师资人力进行最大化利用。

 

二、目的

提升师资利用率,在相同班级情况下使用更少的老师,减少师资成本。

 

三、匹配

3.1 班级数据情况

每次续报、拉新会开m个班级,每个班级有自己的标签,并且每个班级会有n节课,每节课的上课时间段不同。

例:课节1 05.05 17:00 - 18:30

 

3.2 老师数据情况

每个业务线会有k个老师,每个老师可以教的课程标签、上课的时段,这些都是由师资维护好的;已经被现有班级占用的时段系统中可查到。

 

3.3 匹配规则

  1. 时段是固定的,每天7个时段;
  2. 老师只能教自身课程标签内的班级;
  3. 老师空闲时段(上课时段 - 现有班级占用时段)需要完全覆盖班级时段;
  4. 老师当前带班量上限为T(10);
  5. 尽量用较少的老师  or  尽量让老师的带班量较为平均

 

3.4 匹配流程

  1. 根据标签找出老师能教哪些班级,这个是前置必须条件;
  2. 老师空闲时段和每个班级需要的时段进行对比,知道老师可以教哪些班级;
  3. 二分图匹配算法进行老师-班级匹配并输出结果;
  4. 增加虚拟位满足老师匹配多结果。

3.4.1 流程2 - 匹配时段

方法一:由于班级的上课顺序、老师空闲时段都是按照时间排好,假设班级有N个课节,老师在这区间有M个空闲时段,那么可以采用双指针进行匹配即可,实现完整体的时间复杂度为O(m+n)。

可以参考下leetcode区间交集:leetcode.cn/problems/in…

 

方法二:借助匹配规则1,由于时段是固定的,每天7个时段,这样可以把时间转化为二进制数据。由于7个时段写例子太复杂了,这里以每天2个时段举例,假设每天10:00 - 11:30 和 17:00 - 18:30 这两个时段进行上课,首课日期是7月8号,班级有2节课,分别是7月8号的10:00 - 11:30 和 7月10号的 17:00 - 18 :30。此时可以认为第一个课节为1、第二个课节为6;那么转为二进制行数据为100001,老师的空闲时段也以上述例子进行转换;在计算的过程中进行与运算即可后和班级转换的二进制相等即可。

时段/日期7.87.97.10
10:00 - 11:30123
17:00 - 18:30456

 

3.4.2 流程3 - 匹配班级

简单理解就是:给一个老师a分配一个班级,该班级没有老师,那这个老师就上该班,如果发现该班有老师b,则看老师b是否能上其他班,如果能上其他班就让老师b去上其他班级,如果不能上其他班级,老师a就没班级可上。

博客文章:blog.csdn.net/qq_39304630…

 

3.4.3 流程4 - 虚拟老师

根据上述做法,每个老师只能安排一个班级;如果此刻有老师A带了3个班、老师B带了8个班、老师C没有带班;并且要分3个班级,在时间不冲突并且老师都能上课的情况下那么:

情况1:如果要让老师带的班级更均匀,三个班级全部分给老师C;

情况2:如果尽量使用较少的老师,分给老师B 2个班级,分给老师A 1个班级。

 

第一步:根据并查集对每个老师可上班级的时段进行分割,例如:现在有三个班级a、b、c;a、c有一部分课节上课时间冲突,那么就可以把老师能上的班级分成两个集合,a、c是一个,b是一个;

第二步:根据二分图匹配算法,排在最前面的老师拥有最优先的分配班级权限;例如:根据第一步,一个老师就可以分割为2个虚拟老师,再根据虚拟老师进行匹配;

第三步:此刻需要看是让老师带班更均匀还是尽量使用较少的老师,根据情况对虚拟老师进行排序。根据上述,排序为:

情况1: C1、C2、A1、A2、B1、B2

情况2: B1、B2、A1、A2、C1、C2