I'm enjoying a journey through Optaplanner. Java isn't my "native" language but to my surprise the (steep?) learning curve of Optaplanner & Drools hasn't driven me to giving up!
What I've got so far:
I've made a project with the necessary classes. For the sake of my question, I'll simplify to: an Employee
class, a Job
class, a Skills
class and the Schedule
class, where I'd like to get my perfect Optaplanned schedule.
My employees class has a variable List<Skill> skills
containing at least 1 skill they have.
My job class contains the same variable List<Skill> reqSkills
(req = required). This contains at least 1 skill necessary to be able to do this job.
I've initialized with some dummy data. Then I run the following rule:
rule "requiredSkills"
when
Employee($skills : skills)
Job(reqskills not memberOf $skills)
then
scoreHolder.addHardConstraintMatch(kcontext, -1);
end
I thought (but here the steep curve for Drools is beating me) this seemed logical: when an employee's skill is not a member of the skill(s) necessary for the job then that's a hard constraint..
The result for my "planning" is always: the first employee that I've put in as dummy data is linked to all jobs...
My feeling is that using memberOf
does not work for lists vs lists. But how do I fix this, as both my employees as my jobs might have/require multiple skills?
I never use the drools construct not memberOf
in OptaPlanner cases. Maybe because of habit, maybe because it slow or brittle).
FWIW, this is very similar to the skill requirement in optaweb-employee-rostering which just uses plain java code constructs inside the Shift
DRL pattern:
rule "Required skill for a shift"
when
Shift(
employee != null,
!getEmployee().hasSkills(getSpot().getRequiredSkillSet()))
then
scoreHolder.addHardConstraintMatch(kcontext, -100);
end