在 Instant @PlanningVariable 上使用 @PlanningId 符号
Using a @PlanningId notation on an Instant @PlanningVariable
我目前正在设置一个基于甘特图的计划问题,用户可以在其中选择他们想要计划的任务,OptaPlanner 会为他们完成。
我使用增量 Java 分数计算,而不是 drools 引擎。
我的问题是 OptaPlanner 不会将 Instant 作为计划变量,因为它无法为其找到 PlanningId。
我一直坚持让 OptaPlanner 使用多线程。
我目前的模型似乎有缺陷,或者我不了解如何正确使用 OptaPlanner。
我尝试将 Instant 隐藏在另一个 class 后面,但仍然没有帮助。
我的模型只使用一个 PlanningEntity,这是一个任务。
这是我的@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;
}
}
在我的配置中,我将其添加到求解器标签中:
<moveThreadCount>AUTO</moveThreadCount>
这给了我一个例外:
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)
[...]
我希望 OptaPlanner 使用任务的 ID,但它似乎需要每个 PlanningVariables 的 ID。我可以在 Machine 上添加 ID,但不能在 Instant 上添加。
A java.time.Instant
是不可变的,因此任何查找都可以 return 相同的对象实例。就像 Integer、Double、LocalDate 等一样,不需要 @PlanningId
开头。这暴露了 OptaPlanner 中的 3 个问题:
- LookUpStrategyResolver.java 的内置决策缓存也必须包含 Instant。 I've fixed this issue in this PR for 7.20.
- 应该可以配置额外的不可变 类。
- 应该可以在第 3 方外部配置 @PlanningId 类。
请在 issues.jboss.org 项目 PLANNER 上为 2. 和 3. 创建一个 jira。
我目前正在设置一个基于甘特图的计划问题,用户可以在其中选择他们想要计划的任务,OptaPlanner 会为他们完成。
我使用增量 Java 分数计算,而不是 drools 引擎。 我的问题是 OptaPlanner 不会将 Instant 作为计划变量,因为它无法为其找到 PlanningId。
我一直坚持让 OptaPlanner 使用多线程。 我目前的模型似乎有缺陷,或者我不了解如何正确使用 OptaPlanner。
我尝试将 Instant 隐藏在另一个 class 后面,但仍然没有帮助。
我的模型只使用一个 PlanningEntity,这是一个任务。
这是我的@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;
}
}
在我的配置中,我将其添加到求解器标签中:
<moveThreadCount>AUTO</moveThreadCount>
这给了我一个例外:
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)
[...]
我希望 OptaPlanner 使用任务的 ID,但它似乎需要每个 PlanningVariables 的 ID。我可以在 Machine 上添加 ID,但不能在 Instant 上添加。
A java.time.Instant
是不可变的,因此任何查找都可以 return 相同的对象实例。就像 Integer、Double、LocalDate 等一样,不需要 @PlanningId
开头。这暴露了 OptaPlanner 中的 3 个问题:
- LookUpStrategyResolver.java 的内置决策缓存也必须包含 Instant。 I've fixed this issue in this PR for 7.20.
- 应该可以配置额外的不可变 类。
- 应该可以在第 3 方外部配置 @PlanningId 类。
请在 issues.jboss.org 项目 PLANNER 上为 2. 和 3. 创建一个 jira。