I'm very confused about this. Even ChatGPT is unsure of what's wrong. So I need to turn to the real experts.
My project can be found here: https://github.com/matthewjd24/OptaPlanner-Scheduler
This code has been adapted from the Hello world quick start. In summary, I have a job shop scheduling problem, but there are no 'projects' - each job just needs to pass through a machine once and it's done. My hard and soft constraints work fine, but if I attempt to add a new problem fact/planning variable, it starts breaking the hard constraints and acting like it hasn't (as in, the hard score in the resulting solution is 0). I'll show you some relevant snippets of code:
This is my Planning Solution class:
@PlanningSolution
public class TimeTable {
@ValueRangeProvider
@ProblemFactCollectionProperty
private List<Cycle> timeslotList;
@ValueRangeProvider
@ProblemFactCollectionProperty
private List<Machine> machineList;
@ValueRangeProvider
@ProblemFactCollectionProperty
private List<Mold> moldList;
@PlanningEntityCollectionProperty
private List<Job> lessonList;
@PlanningScore
private HardSoftScore score;
This is my Planning Entity, the Job class:
@PlanningEntity
public class Job {
@PlanningId
private Long id;
public String jobName;
public Integer width;
public Integer height;
public Integer weight;
@PlanningVariable(nullable = true)
private Cycle timeslot;
@PlanningVariable(nullable = true)
private Machine machine;
@PlanningVariable(nullable = true)
private Mold mold;
public Job() {
}
public Job(Long id, String jobName, Integer width, Integer height, Integer weight) {
this.id = id;
this.jobName = jobName;
this.width = width;
this.height = height;
this.weight = weight;
}
My constraint that applies a hard score penalty when two jobs have the same timeslot, same machine, and different IDs:
private Constraint machineProcessOneJobAtATime(ConstraintFactory constraintFactory) {
return constraintFactory
.forEach(Job.class)
.join(Job.class,
Joiners.equal(Job::getTimeslot),
Joiners.equal(Job::getMachine),
Joiners.lessThan(Job::getId))
.penalize(HardSoftScore.ONE_HARD)
.asConstraint("Multiple jobs scheduled for a machine at once");
}
If I comment out the @ValueRangeProvider and @ProblemFactCollectionProperty modifiers for the moldList in the planning solution, and @PlanningVariable(nullable = true) in the Job class, the constraint works fine. But the moment I add in the mold list as a variable, OptaPlanner starts breaking this hard constraint and saying the hard score is 0 (essentially acting like it hasn't broken the constraint). I have no constraints set up that interact with the Mold variable. Does anyone know why the machineProcessOneJobAtATime would stop working properly when the Mold planning variable is added? I'm very confused about this. Thank you.