我的目标是使用 Timefold Solver 在员工之间均匀分配任务。
我遇到了两种似乎可以实现这一目标的方法:
选择排序器重量工厂
int leftEmployeeWorkedHours = scoreDirector.computeConstraintWeight(
"Employee worked hours",
ConstraintCollectors.sum(shiftAssignment -> shiftAssignment.getEmployee().equals(leftShiftAssignment.getEmployee()) ? shiftAssignment.getDuration() : 0)
);
int rightEmployeeWorkedHours = scoreDirector.computeConstraintWeight(
"Employee worked hours",
ConstraintCollectors.sum(shiftAssignment -> shiftAssignment.getEmployee().equals(rightShiftAssignment.getEmployee()) ? shiftAssignment.getDuration() : 0)
);
// Compare the total worked hours to achieve load balancing
return Integer.compare(leftEmployeeWorkedHours, rightEmployeeWorkedHours);
另一种选择是使用像这样的约束
[引用自https://docs.timefold.ai/timefold-solver/latest/constraints-and-score/load-balancing-and-fairness]
Constraint fairAssignments(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(ShiftAssignment.class)
.groupBy(ConstraintCollectors.loadBalance(ShiftAssignment::getEmployee))
.penalizeBigDecimal(HardSoftBigDecimalScore.ONE_SOFT, LoadBalance::unfairness)
.asConstraint("fairAssignments");}
我的理解是,如果目标是影响选择过程,例如平衡工作负载或优先考虑首选选项,那么 SelectionSorterWeightFactory 方法可能更合适。另一方面,约束工厂方法更适合驱动资源限制和业务规则。
但是,我想更清楚地了解以下内容:
我什么时候应该选择一种方法而不是另一种,或者我应该使用一种方法 两者的结合?
两种方法之间的主要区别是什么,以及如何做 它们影响求解器的决策过程?
您能否提供有关如何进行的任何其他见解或指南 为我的用例选择合适的方法?
非常感谢您对这些方面的澄清。感谢您的时间和帮助。
如果问题需要负载平衡,则它需要受到约束,并且需要适当加权。这是确保求解器真正考虑到这一点的唯一方法 - 请记住,最终,对求解器来说唯一重要的是找到最佳分数;如果约束不包括负载平衡,则解决方案将不平衡。
就我个人而言,我会远离选择器的晦涩调整。那里有无数的选择,彼此之间有各种各样的相互作用。我发现进入这个兔子洞会浪费大量时间,但通常不会带来任何实际好处。
YMMV,但如果你决定这样做,绝对要确保对你所做的每一个调整进行基准测试。只需确保您使用的调整已被证明可以在各种数据集上提供改进的解决方案。一个样本量是远远不够的。