Question

I am currently writing an application for course scheduling using OptaPlanner and Drools. One of our rules written in Drools collects Entries (time slots of a schedule) of the same day into an ArrayList.

I noticed during testing our rules that this rule fired multiple times, namely the exact amount of entries that are found by collecting them. I assume the reason why this rule fires so many times is due to recombination of the entries that are found (aka backtracking) ie. when there are 10 entries on the same day, this rules fires 10 times

Is there any way to cancel this behaviour?

In case it might help to reason about my problem, here's the rule of which I'm talking about:

rule spareHoursViolated
        when
            $traject : Traject()
            Date($day := day, $month := month, $year := year) 
            $lecturesOnSameDay: ArrayList() from collect 
                        (Entry($day := startingDate.day, 
                                $month := startingDate.month,
                                $year := startingDate.year, courseComponent.course 
                                         memberOf $traject.courses))
        then
            sort($lecturesOnSameDay);
            scoreHolder.addSoftConstraintMatch(kcontext,
            checkSpareHoursAndNoonBreak($lecturesOnSameDay));
end
Was it helpful?

Solution

By implementing checkSpareHoursAndNoonBreak() in the RHS side, it doesn't do delta based score calculation as much as it could. (See docs section on incremental / delta based score calculation).

I'd try to write the rule something like this:

when 
   $t : Traject()
   $l1 : Lecture(traject == $t, $d : day, $p1 : period)
   // Another lecture on the same day, but after the original one
   $l3 : Lecture(traject == $t, day == $d, period > $p1, $p3: period)
   // No lecture in between
   not Lecture(traject == $t, day == $d, period > $p1, period < $p3)
   // It's not lunch
   eval(!Utils.isLunch($l1, $l3)) // Even better is to move this into the $l3 Lecture part
then
   // It's a spring hour
   scoreHolder.addSoftConstraintMatch(kcontext,
            // Punish more spring hours more
            - ($p3.index - $1.index));
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top