在Instant @PlanningVariable上使用@PlanningId表示法

问题描述 投票:0回答:1

我目前正在设置一个基于甘特的计划化问题,用户可以选择他们想要计划的任务,OptaPlanner会为他们做。

我使用增量Java分数计算,而不是drools引擎。我的问题是OptaPlanner不会将Instant作为计划变量,因为它无法为它找到PlanningId。

我一直坚持让OptaPlanner使用多个线程。我目前的模型似乎有缺陷,或者我不理解如何正确使用OptaPlanner。

我试着掩盖另一个班级后面的Instant,但它仍然没有帮助。

我的模型只使用一个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。我可以在机器上添加ID,但不能在Instant上添加。

optaplanner
1个回答
0
投票

java.time.Instant是不可变的,因此任何查找都可以返回相同的对象实例。就像Integer,Double,LocalDate等一样,没有必要开始使用@PlanningId。这暴露了OptaPlanner中的3个问题:

  1. LookUpStrategyResolver.java的内置决策缓存还必须包含Instant。 I've fixed this issue in this PR for 7.20.
  2. 应该可以配置额外的不可变类。
  3. 应该可以在第3方类外部配置@PlanningId。

请在issues.jboss.org项目PLANNER上为2.和3.创建一个jira。

© www.soinside.com 2019 - 2024. All rights reserved.