user3441584
user3441584

Reputation: 63

Trying to add a value to the score in Optaplanner (using Drools)

I have a very simple (possible too simple) rule I want to enforce in Drools to allow a value to be added to my Hard score in Optaplanner. Basically, in my solution class TaskAssignment, I am generating a taskConflictList, which adds to a taskConflictLog each time there is a conflict:

public List<TaskConflict> calculateTaskConflictList(){
   List<TaskConflict> taskConflictList=new ArrayList<TaskConflict>();
   taskConflictLog=0;
    for(Task leftTask:taskList){
        for(Task rightTask:taskList){
            if(leftTask.solutionEquals(rightTask)==!true){
                if(leftTask.getAssignedDevAsString().equals(rightTask.getAssignedDevAsString())){
                if((rightTask.getAllottedStartTime()<=leftTask.getAllottedStartTime()) //long bit of code here....//){
                    taskConflictList.add(new TaskConflict(leftTask,rightTask));
                    taskConflictLog++;
                }
                }
            }
        }
    }
    return taskConflictList;       
   }

All I then want to do is have the negative of this taskConflictLog act as the Hard Score in Drools. I have currently entered this:

rule "OnlyDoOneTaskAtTime"
when
    $TA:TaskAssignment($tCL:taskConflictLog)

then
    scoreHolder.addHardConstraintMatch(kcontext,-$tCL);

end

But I'm getting an error message $tCL cannot be resolved to a variable

This feels like quite an easy thing to do, but for some reason I can't get my head around it. Is there not a straightforward solution for this

Upvotes: 1

Views: 171

Answers (1)

Geoffrey De Smet
Geoffrey De Smet

Reputation: 27312

In the examples, look for classes ending with Parametrization, such as in exam rostering, in the dataset:

public class InstitutionParametrization extends AbstractPersistable { // SINGLETON per Solution

    private int twoInARowPenalty;
    private int twoInADayPenalty;
    private int periodSpreadLength;
    private int periodSpreadPenalty;
    private int mixedDurationPenalty;
    private int frontLoadLargeTopicSize;
    private int frontLoadLastPeriodSize;
    private int frontLoadPenalty;

    ...
}

Then in the DRL:

rule "twoExamsInADay"
    when
        $institutionParametrization : InstitutionParametrization(twoInADayPenalty != 0)
        $topicConflict : TopicConflict($leftTopic : leftTopic, $rightTopic : rightTopic)
        $leftExam : Exam(topic == $leftTopic, $leftDayIndex : dayIndex, $leftPeriodIndex : periodIndex, period != null)
        $rightExam : Exam(topic == $rightTopic, dayIndex == $leftDayIndex,
            Math.abs($leftPeriodIndex - periodIndex) > 1)
    then
        scoreHolder.addSoftConstraintMatch(kcontext,
                $topicConflict.getStudentSize() * (- $institutionParametrization.getTwoInADayPenalty()));
end

// Exams which share students have to few periods between them
rule "periodSpread"
    when
        $institutionParametrization : InstitutionParametrization(periodSpreadPenalty != 0)
        ...
    then
        scoreHolder.addSoftConstraintMatch(kcontext,
                ... * (- $institutionParametrization.getPeriodSpreadPenalty()));
end

Upvotes: 1

Related Questions