Задача
Я бы хотел оценить агрегированную стоимость решения по правилу слюни. Например, в сценарии школьного расписания работник не должен работать более 40 часов в неделю. Как я могу реализовать этот сценарий в ограничении, используя шаблон TimeGrain?
Экспериментирование
Я сделал две реализации этого сценария, используя EasyScoreCalculator и Drools (см. Код ниже). Реляционная модель выглядит следующим образом:
Расписание представляет одну неделю.
Метод getTotalHours (...) возвращает общее количество часов, запланированных в течение недели.
EasyScoreCalculator
public HardSoftScore calculateScore(Schedule schedule) {
int hardScore = 0;
int softScore = 0;
int maxTimePerWeek = 40;
for (Teacher teacher : schedule.getTeachers()) {
int totalDuration = Schedule.getTotalHours(schedule.getScheduleTimes(),teacher);
System.out.println("totalDuration for teacher: " + totalDuration);
if(totalDuration > maxTimePerWeek)
softScore += totalDuration - maxTimePerWeek;
}
return HardSoftScore.of(hardScore, softScore);
}
Drools
rule "Teacher should have max 40 hours"
when
ScheduleTime(teacher != null, $teacher : teacher)
Schedule($scheduleTimes: scheduleTimes)
then
int totalDuration = Schedule.getTotalHours($scheduleTimes, $teacher);
System.out.println("totalDuration for teacher: " + totalDuration);
if( totalDuration > 40){
scoreHolder.penalize(kcontext, totalDuration - 40);
}
end
Файл drool настроен правильно, так как другие ограничения работают правильно.
Результат
Первое решение работает хорошо, но согласно документации EasyScoreCalculator может вызвать проблемы с производительностью.
Второй не работает, так как вывод консоли никогда не выполняется. Однако, если я удаляю Schedule($scheduleTimes: scheduleTimes)
и связанный с ним код, выполняется предложение «then». Как я могу получить агрегированный результат сценария для этого случая в Drools?