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
Uh oh!
There was an error while loading. Please reload this page.
-
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