为什么对链接计划实体的约束会导致以下分数损坏异常?

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

我目前正在致力于解决包含取货和送货的 VRP。在当前模型中,

Vehicle
是我的第一个
@PlanningEntity
,包含
@PlanningListVariable
LoadJobs
,可以是
PICKUP
DROPOFF
类型。每个
LoadJob
都引用它正在传递的
Load
,并且
Load
类都引用它的
PICKUP
DROPOFF
LoadJob

我编写了以下约束,以确保两个

LoadJobs
都放在同一个
Vehicle
上(当然,尝试传递从未被拾起的负载是没有意义的,并且拿起货物而不交付它):

fun pickupAndDropoffOnSameVehicle(constraintFactory: ConstraintFactory): Constraint {
    return constraintFactory
        .forEach(LoadJob::class.java)
        .filter { it.load.pickup.vehicle != it.load.dropoff.vehicle }
        .penalizeConfigurable()
        .asConstraint(PICKUP_AND_DROPOFF_ON_SAME_VEHICLE)
}

当我在

FULL_ASSERT
模式下运行时,出现以下异常:

Caused by: java.lang.IllegalStateException: Score corruption (100hard): the workingScore (-19init/-100hard/0medium/-11670soft) is not the uncorruptedScore (-19init/-200hard/0medium/-11670soft) after completedAction (LoadJob(id=DROPOFF-loDKrYTAqF5kIfjFM6n4) {null -> Vehicle(idx=0)[0]}):
Score corruption analysis:
  The corrupted scoreDirector has no ConstraintMatch(s) which are in excess.
  The corrupted scoreDirector has 1 ConstraintMatch(s) which are missing:
    com.cargonexx.vehiclerouting.solver.constraint/pickupAndDropoffOnSameVehicle/[LoadJob(id=PICKUP-loDKrYTAqF5kIfjFM6n4)]=-100hard/0medium/0soft
  Maybe there is a bug in the score constraints of those ConstraintMatch(s).
  Maybe a score constraint doesn't select all the entities it depends on, but finds some through a reference in a selected entity. This corrupts incremental score calculation, because the constraint is not re-evaluated if such a non-selected entity changes.
Shadow variable corruption in the corrupted scoreDirector:
  None
    at org.optaplanner.core.impl.score.director.AbstractScoreDirector.assertScoreFromScratch(AbstractScoreDirector.java:637)
    at org.optaplanner.core.impl.score.director.AbstractScoreDirector.assertWorkingScoreFromScratch(AbstractScoreDirector.java:613)
    at org.optaplanner.core.impl.score.director.AbstractScoreDirector.doAndProcessMove(AbstractScoreDirector.java:204)
    at org.optaplanner.core.impl.heuristic.thread.MoveThreadRunner.run(MoveThreadRunner.java:131)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:577)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    at java.base/java.lang.Thread.run(Thread.java:1589)

由于错误消息,我猜测这可能是由两个

LoadJobs
通过
Load
类之间的传递关系引起的。我尝试过仅过滤
PICKUP
,然后再过滤同一辆车并加入
LoadJob::class.java
,然后在两个加载作业上过滤相同的
Load
,然后再过滤同一辆车,一切都无济于事.

此异常的原因是什么?如何解决?

kotlin exception optaplanner timefold
1个回答
0
投票

这是因为增量分数计算如何与

交互
.filter { it.load.pickup.vehicle != it.load.dropoff.vehicle }

没有选择

pickup
dropoff
,因此ConstraintStreams实现(无论是OptaPlanner CS Drools impl,还是Timefold的faster impl),不知道当上车或下车的车辆变量发生变化时,需要将这个约束重新评估(以增量方式实现可扩展性)。

解决方案

类似:

forEach(pickup)
.join(dropoff, equals(getLoad))
.filter(not same vehicle)
.penalize()
© www.soinside.com 2019 - 2024. All rights reserved.