ygeek / schedule

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

schedule

DLX参考资料

实现算法说明

Exact Cover Problem描述了一个二维矩阵,其中的元素为0/1。问题需要找出一些行,使得这些行中的1元素正好覆盖所有列,并且只覆盖一次。

本问题可以转化成Exact Cover Problem,并使用Dancing Links有效解决。

首先需要构造出问题的行和列。

模型构造

模型中,列用来表示限制条件,行用来表示决策。

由于部分限制条件(加粗部分)不能很好地在模型中表达,实际使用时对DLX算法做了调整,将这些条件作为剪枝条件加入到覆盖操作之前。

限制条件

  1. 每更中间相隔时间段最少 X 个小时(如每名员工更与更之间必须间隔最少10个小时)。
  2. 一星期必需且只有 X 日公休。
  3. 公休与公休之间不能超过 X 日。
  4. 可設置分别特定日期每更期望有多少名(范围)员工,其中多少名為經理級,多少名為主任級。
  5. 指定時期內,每個同事可以設置可用的排更類型,可针对每个员工进行配置(如12月1日 ~ 12月3日之间,员工A只排早班、中班; 员工B只排中班、夜班)。
  6. 指定時期內,各员工可以设置每周哪天公休,可针对每个员工进行配置(如12月1日 ~ 12月4日之间,员工A每周三公休)。
  7. 指定時期內,那些人不可以/必須在同一更出現 ,可针对每个员工进行配置(如12月1日 ~ 12月4日之间,员工A和员工B不能出現在同一更, 员工C和员工D必須在同一更)。
  8. 公休与公休之间排的更的类型不能多於2個。

限制条件->列

模型中有四种列

  1. Arrangement: 某一天的某位员工已安排(排到某更或公休都算一种安排)
  2. Vacation:某一周的某位员工休假已安排
  3. Period:某一天的某一更的某一种职位已完成
  4. Prefer:某一天的某位员工设置的排更类型已满足

决策->行

  1. Arrangement:安排某一天的某一更的某种职位。 枚举每一天的每一更的每种职位,按指定人数,对这种职位下的所有员工,生成每一种员工组合,作为一行。 每一行都需要在对应的列下加入“1”节点。包括:
    • 这一天这一更这一种职位对应的Period
    • 对应员工在这一天对应的Arrangement
    • 如果满足对应员工这一天指定的排更类型,对应的Prefer
  2. Vacation:安排某一周的某位员工的休假时间。 枚举每一周的每位员工在这周的公休日期,作为一行。如果员工指定了公休日期,只需生成满足条件的行。 每一行都需要在对应的列下加入“1”节点。包括:
    • 这一周这位员工对应的Vacation
    • 这位员工公休时间对应的Arrangement列(公休算是员工当天的一种安排)
    • 这位员工公休时间对应的Prefer列(公休算是满足员工当天的排更要求)

限制条件放宽

没有限制条件的员工间是相互可替换的(完全对调两个人的安排),存在解的情况下,一般都会存在很多等价的解。 如果在算法中通过惩罚+剪枝的方式来遍历所有解,效率很低。 因此算法只搜索满足所有条件的一个解,这样能保证比较快的搜索速度。限制条件的放宽在产品上(限制条件输入)处理。 通过逐渐放宽限制条件并寻找可行解,来达到寻找近似解的目的。

About


Languages

Language:Python 100.0%