|
|
@@ -28,8 +28,8 @@ public class PlanningConstraintProvider implements ConstraintProvider {
|
|
|
competencyConflict(constraintFactory), mealMaxAttendee(constraintFactory),
|
|
|
// Soft constraints are only implemented in the "complete"
|
|
|
// implementation
|
|
|
- competencyTeachingEffort(constraintFactory), preferenceApplication(constraintFactory),
|
|
|
- balanceLoad(constraintFactory)};
|
|
|
+ volunteerMinRestTime(constraintFactory), competencyTeachingEffort(constraintFactory),
|
|
|
+ preferenceApplication(constraintFactory), balanceLoad(constraintFactory)};
|
|
|
}
|
|
|
|
|
|
private Constraint completeAllTimeslot(ConstraintFactory constraintFactory) {
|
|
|
@@ -62,6 +62,24 @@ public class PlanningConstraintProvider implements ConstraintProvider {
|
|
|
.penalize("Volonteer conflict", HardSoftScore.ONE_HARD);
|
|
|
}
|
|
|
|
|
|
+ private Constraint volunteerMinRestTime(ConstraintFactory constraintFactory) {
|
|
|
+ // a volonteer cannot go to 2 timeslot without a 30 min break.
|
|
|
+
|
|
|
+ // Select a assignement ...
|
|
|
+ return getAssignedSlotStream(constraintFactory)
|
|
|
+ // ... and pair it with another assignement ...
|
|
|
+ .join(Assignement.class,
|
|
|
+ // ... in the same volunteer ...
|
|
|
+ Joiners.equal(Assignement::getVolonteer),
|
|
|
+ // ... and the pair is unique (different id, no reverse pairs)
|
|
|
+ Joiners.lessThan(Assignement::getId),
|
|
|
+ // get only overlapping timeslot
|
|
|
+ Joiners.lessThan(Assignement::getStartDateTime, Assignement::getRestEndDateTime),
|
|
|
+ Joiners.greaterThan(Assignement::getRestEndDateTime, Assignement::getStartDateTime))
|
|
|
+ // then penalize each pair with a hard weight.
|
|
|
+ .penalize("Volonteer rest time", HardSoftScore.ONE_SOFT);
|
|
|
+ }
|
|
|
+
|
|
|
private Constraint volunteerMealConflict(ConstraintFactory constraintFactory) {
|
|
|
// a volonteer cannot go to 2 timeslot at the same time.
|
|
|
|