Могу ли я повысить эффективность этого файла OptaPlanner Drools?
Я пытался создать файл Drools для хронометража, но запуск OptaPlanner занимает много времени, хотя количество сущностей довольно мало (менее 400).
Стратегия позднего принятия по умолчанию очень быстро уменьшает жесткое ограничение, оставляя мягкое ограничение высоким, но достигает предела производительности, прежде чем достичь выполнимости. Поиск по Табу снижает обе оценки, но делает это медленнее, чем "Позднее принятие", а также ударяет в стену перед осуществимостью раньше, чем "Позднее принятие".
Интересно, если некоторые из экспоненциальных или групповых оценщиков написаны неправильно или неэффективно? У меня были некоторые проблемы с тем, что из-за неправильных синтаксических ошибок я получал сообщения, что ObjectTypes не могут быть сопоставлены.
import data.Module
import data.Session
import data.Slot
import data.Program
import data.Staffer
import data.SessionAlternativeGroup
import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder
import enums.SessionType
import java.util.Collections
import data.Constants
global HardSoftScoreHolder scoreHolder;
// Check for one tutor overused in the same slot
rule "staffClash"
when
$s1 : Session($tutors : tutors, $id : ID)
$tutor : Staffer() from $tutors
accumulate($s2 : Session($s2.overlaps($s1)); $tuse1 : sum($s2.getTutorWeeks($tutor)))
eval($tuse1 > 12)
then
scoreHolder.addHardConstraintMatch(kcontext,-1);
end
// Room used for one module cannot be used for others at the same time
// (But it could be used for the same type of session on the same module)
rule "moduleRoomClash"
when
$s1 : Session($mod : module, $typ : type, $room : room, $id : ID)
$s2 : Session(module != $mod, type != $typ, room == $room, $s2.overlaps($s1))
then
scoreHolder.addHardConstraintMatch(kcontext,-1);
end
// Apply badness of time slots
rule "timeBadness"
when
Session($slots : allSlots, $count : students)
Slot ($bad : badness) from $slots
then
scoreHolder.addSoftConstraintMatch(kcontext,0-($bad * $count));
end
// Apply staff dislike of time slots
rule "staffDislikedTime"
when
$s : Session($staff : tutors, $slots : allSlots, $count : students)
$st : Staffer($slot : dislikeSlots) from $staff
eval($slots.contains($slot))
then
scoreHolder.addSoftConstraintMatch(kcontext,0-
(Constants.BADNESS_STAFFER_DISLIKES_SLOT) * $count * ($s.getTutorWeeks($st)));
end
// Non computer sessions can be in computer rooms, but it's better not to
rule "unnecessaryComputerRoom"
when
$s : Session(!needsComputer, room!.isComputer, $count : students)
then
scoreHolder.addSoftConstraintMatch(kcontext,0-
(Constants.BADNESS_UNNECESSARY_COMPUTER_ROOM) * $count);
end
// COMPULSORY, MANDATORY sessions must not clash with ANY other mandatory session on that
// program (if they did, it would be impossible to take that module)
rule "CompulsoryMandatoryClash"
when
Program( $comp : compulsories, $all : all )
$s1 : Session( module memberOf $comp, $ID : ID, mandatory == true )
Session( module memberOf $all, ID > $ID, mandatory == true, overlaps($s1) )
then
scoreHolder.addHardConstraintMatch(kcontext,-1);
end
// COMPULSORY, MANDATORY sessions must have at least ONE session in each altgroup on that
// programme that they do not clash with
rule "ProgrammeCompulsoryPracticalWipeout"
when
Program( $comp : compulsories, $all : all )
$s1 : Session(module memberOf $comp, $ID : ID, mandatory)
SessionAlternativeGroup(module memberOf $all, $sessions : sessions)
forall ($s2 : Session(overlaps($s1)) from $sessions)
then
scoreHolder.addHardConstraintMatch(kcontext,-1);
end
// It's bad for elective modules on a programme to clash.
rule "ProgrammeElectiveLectureClash"
when
Program( $el : electives )
$s1 : Session( module memberOf $el, $ID : ID, mandatory == true )
Session( module memberOf $el, ID > $ID, mandatory == true, overlaps($s1) )
then
scoreHolder.addSoftConstraintMatch(kcontext,0-Constants.BADNESS_ELECTIVE_CLASH);
end
// Lectures should be earlier in the week than practicals
rule "LecturesBeforePracticals"
when
Session ($module : module, isLecture, $lecslot : slot)
Session (module == $module, !isLecture, (slot!.ordinal) < ($lecslot!.ordinal))
then
scoreHolder.addHardConstraintMatch(kcontext,-1);
end
// Mandatory sessions shouldn't overlap any sessions on the same module
// (practicals CAN overlap each other, and normally would)
rule "PracticalOverLecture"
when
$s1 : Session ($mod : module, $ID : ID, mandatory)
$s2 : Session (module == $mod, ID > $ID, $s1.overlaps($s2))
then
scoreHolder.addHardConstraintMatch(kcontext,-1);
end
// Elective sessions of different types on the same module
// shouldn't completely overlap each other
rule "MultipleTypesOverlap"
when
$s1 : Session ($mod : module, $ID : ID, $type : type, !mandatory)
$ag : SessionAlternativeGroup($mod == module, type == $type, $s2s : sessions)
forall ($s2 : Session(overlaps($s1)) from $s2s);
then
scoreHolder.addHardConstraintMatch(kcontext,-1);
end
// Sessions on a module should be as close as possible to each other
rule "PracticalsNearLectures"
when
$lec : Session (lastSlot != null, $mod : module, $ID : ID)
$prac : Session (slot != null, module == $mod, $count : students, ID > $ID)
then
scoreHolder.addSoftConstraintMatch(kcontext,
$count * (Math.min(0,0-($prac.getSlot().ordinal - ($lec.getLastSlot().ordinal+1)))));
end
// 12pm or 1pm slot should be free for staff for lunch
rule "NoLunchForYouStaffer"
when
Session($tutors : tutors, $day : slot.day, containsDayOrdinal(4))
$tutor : Staffer() from $tutors
Session(tutors contains $tutor, slot.day == $day, containsDayOrdinal(5))
then
scoreHolder.addHardConstraintMatch(kcontext,-1);
end
// 12pm or 1pm slot should be free for students, for lunch
rule "NoLunchForYouStudent"
when
Program ($comp : compulsories)
Session($day : slot.day, $comp contains module, containsDayOrdinal(4))
Session(slot.day == $day, $comp contains module, containsDayOrdinal(5))
then
scoreHolder.addHardConstraintMatch(kcontext,-1);
end
// Number of days staff members are in should be fairly distributed
rule "StaffInDaysFairness"
when
$s : Staffer(isAL == false)
accumulate(Session(tutors contains $s, $day : slot!.day); $days1 : count($day))
then
scoreHolder.addSoftConstraintMatch(kcontext,(int)-(($days1 ^ 2)));
end
// Staff should have a clear day
rule "StaffClearDay"
when
$s : Staffer(isAL == false)
accumulate(Session(tutors contains $s, $day : slot!.day != 2); $days1 : count($day))
eval(($days1 > 3))
then
scoreHolder.addHardConstraintMatch(kcontext,-1);
end
1 ответ
INFO
регистрация выводит оценку скорости счета. Бенчмаркер (даже лучше) даже показывает это на графике. Чем выше, тем лучше.
Выполните 40-секундную пробежку, прокомментируйте части правил и проследите, как вычисляется скорость, чтобы найти узкие места.