I would like to test if the count (after grouping by technician, numberOfTasksByTechnician) above average for a good balance of tasks for technicians (every technician must do the same number of tasks), how can I get the average (hard coded value 4)
Constraint technicianCharge(ConstraintFactory constraintFactory) {
return constraintFactory.from(Task.class)
.groupBy(
Task::getTechnician, ConstraintCollectors.countDistinct()
)
.filter((technician, count)-> {
return count > 4; // return count > (?average)
})
.penalize("technicianCharge", HardSoftScore.ONE_SOFT);
}
At the moment, to collect average, you need to write a custom constraint collector. It's not hard to do, check out count() implementation for inspiration. When you have your constraint collector, your constraint stream would then look like this:
Constraint technicianCharge(ConstraintFactory constraintFactory) {
return constraintFactory.from(Task.class)
.groupBy(
Task::getTechnician,
ConstraintCollectors.countDistinct(),
MyConstraintCollectors.average(task -> ...)
)
.filter((technician, count, average)-> {
return count > average;
})
.penalize("technicianCharge",
HardSoftScore.ONE_SOFT,
(technician, count, average) -> count - average);
}
In the future, we may provide the average constraint collector out-of-the-box .
As a footnote, since you mentioned fairness, you may want to see our blog on OptaPlanner load balancing and fairness .
As of OptaPlanner 8.11.0.Final, 'average' is available out of the box.
https://www.optaplanner.org/blog/2021/08/19/ConstraintStreamsSomeMoreLove.html
cheers :D
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.