如何处理Optaplanner中的循环可用性?



我在Optaweb(目前已停产)平台上工作,我有一个EmployeeAvailability类,我可以定义startDateTimeendDateTime和状态(以下之一:UNAVAILABLE,UNDESIRED,DESIRED)。然而,这些都是个别事件。我想要的是EmployeeAvailability是一个循环的事件。我可以定义它的递归性(例如每周五),然后在计划班次时自动处理它。我该怎么做呢?我不是在寻找非常具体的说明,而是在更高层次上理解如何做到这一点。

现在,我试着通过在每个EmployeeAvailability上设置一个标志isRecurring来解决这个问题,然后当我计划下周时,我运行一个函数来复制所有EmployeeAvailabilityisRecurring == True在过去的一周。这适用于每周循环,但它是一个相当手动的过程。

理想情况下,我希望:

  • 能够定义任何复发模式(每周,每月,每天等)。也许我可以通过https://www.kanzaki.com/docs/ical/rrule.html
  • 存储递归
  • 数据库中没有单独的EmployeeAvailability对象,而是只有一个定义重复模式的对象。这个对象可以转换成单独的对象,当他们需要显示在前端或当他们需要解决由求解器?我不推荐这个:https://github.com/bmoeskau/Extensible/blob/master/recurrence-overview.md

一种方法是创建一个新类EmployeeAvailabilityPattern,它有一个方法appliesToShift(Shift),如果Shift匹配可用性模式,该方法返回true,否则返回false。然后匹配EmployeeAvailabilityPattern的约束看起来像这样:

private static BiConstraintStream<EmployeeAvailabilityPattern, Shift> getConstraintStreamWithAvailabilityPatternIntersections(
ConstraintFactory constraintFactory, EmployeeAvailabilityState employeeAvailabilityState) {
return constraintFactory.forEach(EmployeeAvailabilityPattern.class)
.filter(pattern -> pattern.getState() == employeeAvailabilityState)
.join(Shift.class,
equal(EmployeeAvailabilityPattern::getEmployee, Shift::getEmployee))
.filter((pattern, shift) -> pattern.appliesToShift(shift));
}
Constraint unavailablePatternEmployeeTimeSlot(ConstraintFactory constraintFactory) {
return getConstraintStreamWithAvailabilityPatternIntersections(constraintFactory, UNAVAILABLE)
.penalizeConfigurableLong(CONSTRAINT_UNAVAILABLE_TIME_SLOT_FOR_AN_EMPLOYEE,
((employeeAvailability, shift) -> shift.getLengthInMinutes()));
}

最新更新