Search code examples
optaplanner

Optaplanner drools, penalize one 1 entity


I use optaplanner to create a time plan with different lessons. One important rule I need help to solve is minimizing/cut the pauses between each lesson. I use the time-grain pattern so basically, I need a rule that minimizes the amount of time-grains between 2 lessons.

So let say I have a lesson A. How can I find the previously nearest lesson B (in amount of time-grains)?

My temporary solution has been to use a rule that matches lesson A and a collection of lessons that are held the same day (and earlier than lesson A). It seems to work, but when I penalize the lesson it also penalizes all the lesson in the collection.

So my next question is: Based upon a rule match that matches multiple entries, can I only penalize one of them? Here is an example of what I want to achieve:

rule "Horizontal conflict"
    when
        $queen1: Queen($id : id, row != null, $i : rowIndex)
        $queen2: Queen(id > $id, rowIndex == $i)
    then
        //scoreHolder.addConstraintMatch(kcontext, -1);
        only penalize $queen1
end
```

Solution

  • Not knowing the details of your model, I'm going to assume Lesson has a startDate time grain:

    when
        Lesson($firstStart: startDate)
        Lesson($secondStart: startDate, startDate > $firstStart)
        not Lesson(start > $firstStart, start < $secondStart)
    then
        // your penalty is $secondStart - $firstStart
    end
    

    You'll have to tweak the boundary conditions based on your exact requirements, but the main trick is not - you are looking for a pair of lessons which have no lesson inbetween.