A new score calculation method for ConstraintFactory in which you can dynamically set the constraint weight #869
WinterWolfie
started this conversation in
Ideas
Replies: 1 comment 2 replies
-
This can partially be alleviated by reusing part of the constraint stream: BiConstraintStream<Employee, Integer> getHoursWorked(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Shift.class)
.groupBy(Shift::getEmployee, ConstraintCollector.sum(Shift::getDurationInHours));
}
Constraint softMaxHoursWorked(ConstraintFactory constraintFactory) {
return getHoursWorked(constraintFactory)
.filter((employee, hours) -> hours > employee.getPreferredMaxHoursWorked())
.penalize(HardSoftScore.ONE_SOFT, (employee, hours) -> hours - employee.getPreferredMaxHoursWorked())
.asConstraint("Preferred max hours worked");
}
Constraint hardMaxHoursWorked(ConstraintFactory constraintFactory) {
return getHoursWorked(constraintFactory)
.filter((employee, hours) -> hours > employee.getRequiredMaxHoursWorked())
.penalize(HardSoftScore.ONE_SOFT, (employee, hours) -> hours - employee.getRequiredMaxHoursWorked())
.asConstraint("Required max hours worked");
} Or by having a function that act like a "template" for the constraints: Constraint hoursWorkedConstraint(ConstraintFactory constraintFactory, Function<Employee, Integer> limitFunction, HardSoftScore weight, String constraintName) {
return constraintFactory.forEach(Shift.class)
.groupBy(Shift::getEmployee, ConstraintCollector.sum(Shift::getDurationInHours));
.filter((employee, hours) -> hours > limitFunction.apply(employee))
.penalize(weight, (employee, hours) -> hours - limitFunction.apply(employee))
.asConstraint(constraintName);
Constraint softMaxHoursWorked(ConstraintFactory constraintFactory) {
return hoursWorkedConstraint(constraintFactory, Employee::getPreferredMaxHoursWorked, HardSoftScore.ONE_SOFT, "Preferred max hours worked");
}
Constraint hardMaxHoursWorked(ConstraintFactory constraintFactory) {
return hoursWorkedConstraint(constraintFactory, Employee::getRequiredMaxHoursWorked, HardSoftScore.ONE_HARD, "Required max hours worked");
} |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hello, while using Timefold, I often encounter a problem where I have to duplicate constraints. In some scenarios, I want the solving value to reach a specific target value. However, it's not a big problem if the value is not exactly the target value, and it should receive a soft penalty. Nevertheless, the solving value should not, under any circumstances, stray too far away; otherwise, it should receive a hard penalty. To address this, I have to create two constraints that are almost the same, differing only in their constraint weights.
The impact() method for ConstraintFactory helps a lot in similar scenarios, but it would be nice to also be able to return a constraint weight from the lambda function.
What is the likelihood that something like this would be implemented in Timefold, and is this even a good idea?
Beta Was this translation helpful? Give feedback.
All reactions