|
|
@@ -3,7 +3,7 @@ package fr.jaquin.bdlg.planner.solver;
|
|
|
import fr.jaquin.bdlg.planner.domain.Assignement;
|
|
|
import fr.jaquin.bdlg.planner.domain.MealAssignement;
|
|
|
|
|
|
-import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore;
|
|
|
+import org.optaplanner.core.api.score.buildin.hardmediumsoft.HardMediumSoftScore;
|
|
|
import org.optaplanner.core.api.score.stream.Constraint;
|
|
|
import org.optaplanner.core.api.score.stream.ConstraintCollectors;
|
|
|
import org.optaplanner.core.api.score.stream.ConstraintFactory;
|
|
|
@@ -35,13 +35,13 @@ public class PlanningConstraintProvider implements ConstraintProvider {
|
|
|
private Constraint completeAllTimeslot(ConstraintFactory constraintFactory) {
|
|
|
return constraintFactory.from(Assignement.class)
|
|
|
.filter((assignment) -> assignment.getVolonteer() == null)
|
|
|
- .penalize("Timeslot not initialized ", HardSoftScore.ONE_HARD);
|
|
|
+ .penalize("Timeslot not initialized ", HardMediumSoftScore.ONE_HARD);
|
|
|
}
|
|
|
|
|
|
private Constraint feedAllVolunteer(ConstraintFactory constraintFactory) {
|
|
|
return constraintFactory.from(MealAssignement.class)
|
|
|
.filter((assignment) -> assignment.getMealSlot() == null)
|
|
|
- .penalize("Meal not initialized ", HardSoftScore.ONE_HARD);
|
|
|
+ .penalize("Meal not initialized ", HardMediumSoftScore.ONE_HARD);
|
|
|
}
|
|
|
|
|
|
private Constraint volunteerConflict(ConstraintFactory constraintFactory) {
|
|
|
@@ -59,7 +59,7 @@ public class PlanningConstraintProvider implements ConstraintProvider {
|
|
|
Joiners.lessThan(Assignement::getStartDateTime, Assignement::getEndDateTime),
|
|
|
Joiners.greaterThan(Assignement::getEndDateTime, Assignement::getStartDateTime))
|
|
|
// then penalize each pair with a hard weight.
|
|
|
- .penalize("Volonteer conflict", HardSoftScore.ONE_HARD);
|
|
|
+ .penalize("Volonteer conflict", HardMediumSoftScore.ONE_HARD);
|
|
|
}
|
|
|
|
|
|
private Constraint volunteerMinRestTime(ConstraintFactory constraintFactory) {
|
|
|
@@ -77,7 +77,7 @@ public class PlanningConstraintProvider implements ConstraintProvider {
|
|
|
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);
|
|
|
+ .penalize("Volonteer rest time", HardMediumSoftScore.ONE_MEDIUM);
|
|
|
}
|
|
|
|
|
|
private Constraint volunteerMealConflict(ConstraintFactory constraintFactory) {
|
|
|
@@ -93,26 +93,27 @@ public class PlanningConstraintProvider implements ConstraintProvider {
|
|
|
Joiners.lessThan(Assignement::getStartDateTime, MealAssignement::getEndDateTime),
|
|
|
Joiners.greaterThan(Assignement::getEndDateTime, MealAssignement::getStartDateTime))
|
|
|
// then penalize each pair with a hard weight.
|
|
|
- .penalize("Volonteer Meal conflict", HardSoftScore.ONE_HARD);
|
|
|
+ .penalize("Volonteer Meal conflict", HardMediumSoftScore.ONE_HARD);
|
|
|
}
|
|
|
|
|
|
private Constraint competencyConflict(ConstraintFactory constraintFactory) {
|
|
|
// a volonteer must match required competencies.
|
|
|
return getAssignedSlotStream(constraintFactory).penalize("Competence conflict",
|
|
|
- HardSoftScore.ONE_HARD, Assignement::getCompetenceLackScore);
|
|
|
+ HardMediumSoftScore.ONE_HARD, Assignement::getCompetenceLackScore);
|
|
|
}
|
|
|
|
|
|
private Constraint competencyTeachingEffort(ConstraintFactory constraintFactory) {
|
|
|
// We favor volonteer that already have required competencies.
|
|
|
+ // TODO: Idealy you should group by per volonteer and computed missing teachable competencies
|
|
|
return getAssignedSlotStream(constraintFactory).penalize(
|
|
|
- "Avoid teaching competences to volunteer", HardSoftScore.ONE_SOFT,
|
|
|
+ "Avoid teaching competences to volunteer", HardMediumSoftScore.ONE_SOFT,
|
|
|
Assignement::getSoftCompetenceLackScore);
|
|
|
}
|
|
|
|
|
|
private Constraint preferenceApplication(ConstraintFactory constraintFactory) {
|
|
|
// The system should favor timeslots selected by user.
|
|
|
return getAssignedSlotStream(constraintFactory).reward("Preference application",
|
|
|
- HardSoftScore.ONE_SOFT, Assignement::getPreferenceScore);
|
|
|
+ HardMediumSoftScore.ONE_SOFT, Assignement::getPreferenceScore);
|
|
|
}
|
|
|
|
|
|
private Constraint balanceLoad(ConstraintFactory constraintFactory) {
|
|
|
@@ -122,7 +123,7 @@ public class PlanningConstraintProvider implements ConstraintProvider {
|
|
|
// ... look at volunteer and count nulber of associated slots ...
|
|
|
.groupBy(Assignement::getVolonteer, ConstraintCollectors.count())
|
|
|
// then penalize each pair with a hard weight.
|
|
|
- .penalize("Fair workload balance", HardSoftScore.ONE_SOFT,
|
|
|
+ .penalize("Fair workload balance", HardMediumSoftScore.ONE_SOFT,
|
|
|
(volonteer, slotCount) -> slotCount * slotCount);
|
|
|
}
|
|
|
|
|
|
@@ -133,7 +134,7 @@ public class PlanningConstraintProvider implements ConstraintProvider {
|
|
|
.groupBy(MealAssignement::getMealSlot, ConstraintCollectors.count())
|
|
|
.filter((slot, volonteerCount) -> slot.getMaxAttendee() < volonteerCount)
|
|
|
// then penalize each pair with a hard weight.
|
|
|
- .penalize("Meal max attendee", HardSoftScore.ONE_HARD,
|
|
|
+ .penalize("Meal max attendee", HardMediumSoftScore.ONE_HARD,
|
|
|
(slot, volonteerCount) -> (slot.getMaxAttendee() - volonteerCount)
|
|
|
* (slot.getMaxAttendee() - volonteerCount));
|
|
|
}
|