Reputation: 13
I am currently working on setting up a gantt-based planification problem, where a user can choose which tasks they want to plan, and OptaPlanner would do it for them.
I use incremental Java score calculation, and not the drools engine. My issue is that OptaPlanner won't take an Instant as a planning variable, as it isn't able to find a PlanningId for it.
I've been stuck on getting OptaPlanner to use multiple threads. My current model seems to be flawed, or I am not understanding how to use OptaPlanner properly.
I tried masking the Instant behind another class, but it still did not help.
My model uses only one PlanningEntity, which is a task.
Here's a simplified version of my @PlanningEntity :
@PlanningEntity(difficultyComparatorClass = TaskDifficultyComparator.class)
public class Task extends AbstractTask {
private Machine machine;
private Instant start;
@PlanningId
private Integer id;
@PlanningVariable(valueRangeProviderRefs = {"machineRange"}, nullable = true, strengthComparatorClass = MachineStrengthComparator.class)
public Machine getMachine() {
return machine;
}
@PlanningVariable(valueRangeProviderRefs = {"timeRange"}, nullable = true, strengthComparatorClass = StartStengthComparator.class)
public Instant getStart() {
return start;
}
}
In my config, I have this added to the solver tag :
<moveThreadCount>AUTO</moveThreadCount>
This gives me an exception:
Exception in thread "Thread-6" java.lang.IllegalStateException: The move thread with moveThreadIndex (0) has thrown an exception. Relayed here in the parent thread.
at org.optaplanner.core.impl.heuristic.thread.OrderByMoveIndexBlockingQueue.take(OrderByMoveIndexBlockingQueue.java:142)
at org.optaplanner.core.impl.localsearch.decider.MultiThreadedLocalSearchDecider.forageResult(MultiThreadedLocalSearchDecider.java:187)
at org.optaplanner.core.impl.localsearch.decider.MultiThreadedLocalSearchDecider.decideNextStep(MultiThreadedLocalSearchDecider.java:157)
at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(DefaultLocalSearchPhase.java:70)
at org.optaplanner.core.impl.solver.AbstractSolver.runPhases(AbstractSolver.java:87)
[...]
Caused by: java.lang.IllegalArgumentException: The externalObject (2019-04-16T20:31:17.162Z) cannot be looked up.
Maybe give the class (class java.time.Instant) a PlanningId annotation or change the PlanningSolution annotation's LookUpStrategyType or don't rely on functionality that depends on ScoreDirector.lookUpWorkingObject().
at org.optaplanner.core.impl.domain.lookup.NoneLookUpStrategy.lookUpWorkingObject(NoneLookUpStrategy.java:47)
at org.optaplanner.core.impl.domain.lookup.LookUpManager.lookUpWorkingObject(LookUpManager.java:74)
[...]
I expected OptaPlanner to use the tasks' ID, but it seems like it wants an id on each of the PlanningVariables. I am able to add an ID on the Machine, but not on the Instant.
Upvotes: 1
Views: 355
Reputation: 27327
A java.time.Instant
is immutable, so any lookup can just return the same object instance. Just like Integer, Double, LocalDate, etc, there is no need for a @PlanningId
to begin with. This exposes 3 issues in OptaPlanner:
Please create a jira for 2. and 3. on issues.jboss.org project PLANNER.
Upvotes: 1