【问题标题】:OptaPlanner: Drools rule on consecutive shift assignmentsOptaPlanner:Drools 对连续班次分配的规则
【发布时间】:2020-08-12 22:14:58
【问题描述】:

上下文是使用 Drools 规则计算分数的 OptaPlanner 的员工轮班分配。 我的员工不能连续工作超过三天而没有休息日。 我非常愚蠢地实现了这样一个约束:

rule "No more than three consecutive working days"
    when
        ShiftAssignment(
            $id1 : id,
            $empoloyee : empoloyee != null,
            $shift1 : shift
            )
        ShiftAssignment(
            id > $id1,
            empoloyee == $empoloyee,
            shift.isConsecutiveDay($shift1),
            $id2 : id,
            $shift2 : shift
            )
        ShiftAssignment(
            id > $id2,
            empoloyee == $empoloyee,
            shift.isConsecutiveDay($shift2),
            $id3 : id,
            $shift3 : shift
            )
        ShiftAssignment(
            id > $id3,
            empoloyee == $empoloyee,
            shift.isConsecutiveDay($shift10)
            )
    then
        scoreHolder.penalize(kcontext);
end

我希望方法/变量的名称清楚地表明它们的作用/含义。 有没有更方便、更智能的方式来实现这样的规则?请记住,上面的三天可能需要更改为更大的数字(我使用三天来避免规则中更现实的十行或更多代码)。谢谢。

【问题讨论】:

    标签: drools optaplanner


    【解决方案1】:

    如果我们可以假设一名员工每天最多轮班,并且shift.isConsecutiveDay() 可以被shift.day == $shift1.day + 1 替换,则可以使用exists

    when
        ShiftAssignment($employee : empoloyee != null, $shift1 : shift)
        exists ShiftAssignment(employee == $employee, shift.day == $shift1.day + 1)
        exists ShiftAssignment(employee == $employee, shift.day == $shift1.day + 2)
        exists ShiftAssignment(employee == $employee, shift.day == $shift1.day + 3)
    then
    

    如果不能做出这样的假设,您的解决方案应该可行,但需要考虑一个潜在的极端情况:

    该规则尝试通过条件id > $id1 过滤掉相同班次的组合。此条件有效,但 ID 必须在班次时按升序生成,否则会与 shift.isConsecutiveDay(...) 冲突。如果无法保证此属性,最好检查 ID 不等式。

    【讨论】:

    • 感谢您的回答。实际上,我希望有一个不同的解决方案:现在想象一下,您想以某种方式将连续天数从三天“缩放”到十:使用您的规则和我的规则您需要添加新行。这正是我想要避免的(如果可能的话)。
    • ID 实际上是从类的static 属性生成的Long:当班次创建时(按时间顺序),新的ID 正在生成(按升序)。
    • 我理解增加规则中的连续天数的担忧。解决此问题的一种方法是使用Drools accumulate,可能使用自定义累积函数实现。
    【解决方案2】:

    我使用了多种规则来实现这一点。第一条规则设置连续工作序列的开始,第二条设置结束,第三条规则创建一个“工作序列”以适应开始和结束之间。最后,“最长连续天数”规则实际上会根据连续天数的限制检查您的“工作顺序”。

    这个范例实际上是在护士排班示例中: https://github.com/kiegroup/optaplanner/blob/master/optaplanner-examples/src/main/resources/org/optaplanner/examples/nurserostering/solver/nurseRosteringConstraints.drl

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 2022-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多