我正在尝试学习如何在时间折叠中使用用于约束流的不同类型的构建块。为此,我使用员工调度示例作为基础并对其进行修改。我想添加一个约束,限制员工可以连续工作的天数,即分配给一个班次,考虑到一个班次属于其开始时间所在的那一天。连续工作日限制设置为4。
我按照时间折叠文档的分数计算部分的第 4.5.7 节中的连续匹配示例编写了此约束代码
Constraint maxConseutiveDays(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Shift.class)
.filter(shift -> shift.getEmployee() != null)
.groupBy(Shift::getEmployee,
ConstraintCollectors.toConsecutiveSequences(Shift::getStart, Shift::getId))
.flattenLast(SequenceChain::getConsecutiveSequences)
.filter((employee, shifts) -> shifts.getCount() > 4)
.penalize(HardSoftScore.ONE_HARD)
.asConstraint("Maximum consecutive working days exceeded");
}
但是,我不断收到构建错误,尤其是显示
no suitable method found for toConsecutiveSequences(Shift::getStart,Shift::getId)
的错误。有人可以向我提供有关 toConsecutiveSequences
函数所需参数的更多详细信息,或者帮助我找到错误的信息吗?
编译器告诉您,类
toConsecutiveSequences
上没有方法 ConstraintCollectors
可以接受这些参数。如果我们看一下这个类,我们就会发现它是真的;你的 filter
会产生 UniConstraintStream
,为此,唯一可用的方法是:
<A> UniConstraintCollector<A, ?, SequenceChain<A, Integer>> toConsecutiveSequences(ToIntFunction<A> indexMap) {
...
}
如您所见,该方法只接受一个参数。你给它两个。你的
groupBy
应该看起来像这样:
.groupBy(Shift::getEmployee, ConstraintCollectors.toConsecutiveSequences(Shift::getId))
当我审查你的约束时,我还在你的定义中发现了一个分数陷阱。您总是希望对较大的违规行为进行更多处罚,以帮助解决者区分不同的解决方案。解决这个问题后,您的约束将如下所示:
Constraint maxConseutiveDays(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Shift.class)
.filter(shift -> shift.getEmployee() != null)
.groupBy(Shift::getEmployee,
ConstraintCollectors.toConsecutiveSequences(Shift::getStart, Shift::getId))
.flattenLast(SequenceChain::getConsecutiveSequences)
.filter((employee, shifts) -> shifts.getCount() > 4)
.penalize(HardSoftScore.ONE_HARD, (employee, shifts) -> shifts.getCount())
.asConstraint("Maximum consecutive working days exceeded");
}