schedule
DLX参考资料
实现算法说明
Exact Cover Problem描述了一个二维矩阵,其中的元素为0/1。问题需要找出一些行,使得这些行中的1元素正好覆盖所有列,并且只覆盖一次。
本问题可以转化成Exact Cover Problem,并使用Dancing Links有效解决。
首先需要构造出问题的行和列。
模型构造
模型中,列用来表示限制条件,行用来表示决策。
由于部分限制条件(加粗部分)不能很好地在模型中表达,实际使用时对DLX算法做了调整,将这些条件作为剪枝条件加入到覆盖操作之前。
限制条件
- 每更中间相隔时间段最少 X 个小时(如每名员工更与更之间必须间隔最少10个小时)。
- 一星期必需且只有 X 日公休。
- 公休与公休之间不能超过 X 日。
- 可設置分别特定日期每更期望有多少名(范围)员工,其中多少名為經理級,多少名為主任級。
- 指定時期內,每個同事可以設置可用的排更類型,可针对每个员工进行配置(如12月1日 ~ 12月3日之间,员工A只排早班、中班; 员工B只排中班、夜班)。
- 指定時期內,各员工可以设置每周哪天公休,可针对每个员工进行配置(如12月1日 ~ 12月4日之间,员工A每周三公休)。
- 指定時期內,那些人不可以/必須在同一更出現 ,可针对每个员工进行配置(如12月1日 ~ 12月4日之间,员工A和员工B不能出現在同一更, 员工C和员工D必須在同一更)。
- 公休与公休之间排的更的类型不能多於2個。
限制条件->列
模型中有四种列
- Arrangement: 某一天的某位员工已安排(排到某更或公休都算一种安排)
- Vacation:某一周的某位员工休假已安排
- Period:某一天的某一更的某一种职位已完成
- Prefer:某一天的某位员工设置的排更类型已满足
决策->行
- Arrangement:安排某一天的某一更的某种职位。
枚举每一天的每一更的每种职位,按指定人数,对这种职位下的所有员工,生成每一种员工组合,作为一行。
每一行都需要在对应的列下加入“1”节点。包括:
- 这一天这一更这一种职位对应的Period列
- 对应员工在这一天对应的Arrangement列
- 如果满足对应员工这一天指定的排更类型,对应的Prefer列
- Vacation:安排某一周的某位员工的休假时间。
枚举每一周的每位员工在这周的公休日期,作为一行。如果员工指定了公休日期,只需生成满足条件的行。
每一行都需要在对应的列下加入“1”节点。包括:
- 这一周这位员工对应的Vacation列
- 这位员工公休时间对应的Arrangement列(公休算是员工当天的一种安排)
- 这位员工公休时间对应的Prefer列(公休算是满足员工当天的排更要求)
限制条件放宽
没有限制条件的员工间是相互可替换的(完全对调两个人的安排),存在解的情况下,一般都会存在很多等价的解。 如果在算法中通过惩罚+剪枝的方式来遍历所有解,效率很低。 因此算法只搜索满足所有条件的一个解,这样能保证比较快的搜索速度。限制条件的放宽在产品上(限制条件输入)处理。 通过逐渐放宽限制条件并寻找可行解,来达到寻找近似解的目的。