drools - OptaPlanner:Drools 对连续班次分配的规则
问题描述
上下文是使用 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
我希望方法/变量的名称清楚地揭示了它们的作用/含义。有没有更方便、更智能的方式来实现这样的规则?请记住,上面的三天可能需要更改为更大的数字(我使用三天来避免规则中更现实的十行或更多行代码)。谢谢。
解决方案
如果我们可以假设员工每天最多轮班,并且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 不等式。
推荐阅读
- arrays - 根据 Missy Elliott 的歌曲 Work It,哪些数据结构既可以翻转又可以反转?
- python - 如何在 Windows 中将 Poppler 安装到虚拟环境中(Pycharm)
- google-iap - 有没有办法通过 API 将资源身份验证方法更改为外部?
- go - 在 Go 构建约束中,OMIT 是什么意思?
- javascript - 将背压逻辑应用于发生器的有效方法?
- xamarin.forms - VS 2019 中的 Xamarin.Forms 新项目对话框没有“Shell”模板选项
- autohotkey - AutoHotkey 映射 F12 以进行四次击键
- html - 加载通过 iframe 嵌入的 Instagram 时收到未捕获(承诺中)未定义错误
- flutter - 如何在 Flutter 中使用动画更改行/列状态?
- javascript - onsubmit JS 脚本不会重定向到正确的位置