Geoffrey De Smet
Build your own model
by Geoffrey De Smet
for (Shift shift : shifts) {
if (!shift.employee.skills
.contains(shift.requiredSkill)) {
return true;
}
}
return false;
Constraint requiredSkill(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Shift.class)
.groupBy(ConstraintCollectors.toList()) // BAD
.filter(shifts -> {
for (Shift shift : shifts) {
if (!shift.employee.skills
.contains(shift.requiredSkill)) {
return true;
}
}
return false;
})
.penalize(ONE_HARD)
.asConstraint("Missing required skill");
}
Constraint requiredSkill(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Shift.class)
.filter(shift -> !shift.employee.skills
.contains(shift.requiredSkill))
.penalize(ONE_HARD)
.asConstraint("Missing required skill");
}
Avoids a score trap.
@Test
void requiredSkill() {
var employee = new Employee("Amy", Set.of());
constraintVerifier.verifyThat(
MyConstraintProvider::requiredSkill)
.given(employee,
new Shift("Plumber", employee))
.penalizes(1);
}
@Test
void requiredSkill() {
var employee = new Employee("Beth", Set.of("Plumber"));
constraintVerifier.verifyThat(
MyConstraintProvider::requiredSkill)
.given(employee,
new Shift("Plumber", employee))
.penalizes(0);
}
Constraint dependencyTask(...) {
return constraintFactory.forEach(Task.class)
.filter(task ->
task.start < task.dependencyTask.end)
.penalize(ONE_HARD)
.asConstraint("Starts before dependency task");
}
Constraint dependencyTask(...) {
return constraintFactory.forEach(Task.class)
.join(Task.class, equal(task -> task,
task -> task.dependencyTask)
.filter(task1, task2 ->
task1.start < task2.end)
.penalize(ONE_HARD)
.asConstraint("Starts before dependency task");
}
Learn more | docs.timefold.ai |
---|---|
Get started | timefold-quickstarts |
Feedback | Geoffrey De Smet |