我开始工作切换到 ConstraintStreams,部分更新到最新的 OptaPlanner(即,
8.35.0.Final
,截至撰写本文时)从 8.22.1.Final
.
沿线的某个地方,以下配置 XML 已停止工作。所以,我想知道,这两个版本之间是否存在向后不兼容的变化,w.r.t.配置 xml?
到目前为止,我能够调试的最深的是
DefaultConstructionHeuristicPhase
,在第 45 行,entityPlacer
返回一个 Iterator
而不是 hasNext
.
这个 CH 阶段是 LS 阶段之前的最后一个阶段,我只在 LS 阶段开始后看到一个异常,这是由于未初始化的分数。
我会在明天早上尝试获得一个最小的复制器和示例,但就目前而言,这是我所拥有的最好的。我想有人可能会立即看到这个问题。
<constructionHeuristic>
<cacheType>PHASE</cacheType>
<queuedEntityPlacer>
<entitySelector id="id">
<entityClass>com.blah.MyClass</entityClass>
</entitySelector>
<cartesianProductMoveSelector>
<selectedCountLimit>200</selectedCountLimit>
<changeMoveSelector>
<entitySelector mimicSelectorRef="id" />
<valueSelector variableName="pv1" />
</changeMoveSelector>
<changeMoveSelector>
<entitySelector mimicSelectorRef="id" />
<valueSelector variableName="pv2" />
</changeMoveSelector>
<changeMoveSelector>
<entitySelector mimicSelectorRef="id" />
<valueSelector variableName="pv3" />
</changeMoveSelector>
<changeMoveSelector>
<entitySelector mimicSelectorRef="id" />
<valueSelector variableName="pv4" />
</changeMoveSelector>
</cartesianProductMoveSelector>
</queuedEntityPlacer>
</constructionHeuristic>
尽管这是一个次要的版本增加,但这个版本的提升似乎引入了几个向后不兼容的更改。到目前为止,它们很小,但我不能确定此配置中的某些内容已被弃用。
问题似乎在
SolutionDescriptor::visitEntitiesByEntityClass
。见差异。提交更改 - 我认为 - 导致此问题.
在更改之前,
line 945
在将entityClass.isInstance(entity)
添加到entity
之前检查了entityList
。然而,现在line 951
在调用entityClass.isAssignableFrom(typeParameter)
visitor
之前检查Consumer
。
但是,我的
Solution
课只是在 interface
上指定 @PlanningEntity
的 @PlanningEntityCollectionProperty
,就像这样:
@Override
@PlanningEntityCollectionProperty
@ValueRangeProvider(id = "vrpName")
public List<IEntity> getEntities() {
return super.getLinks();
}
因此
typeParameter
中的 visitEntitiesByEntityClass
是 interface
IEntity
和 implementation.isAssignableFrom(implInterface) == false
根据
isAssignableFrom
JavaDoc:
确定此 Class 对象表示的类或接口是否与指定的 Class 参数表示的类或接口相同,或者是它们的超类或超接口。如果是,则返回 true;否则返回 false。
所以
visitor
Consumer
永远不会被调用,ConstructionHeuristic
SolverJob
被告知它没有可以采取的行动,我们很早就崩溃了,分数初始化不足。
综上所述,我不太确定最好的修复方法是什么,或者是否真的存在错误,我不只是把事情搞得一团糟。但是,我有一个解决方法:
为了让我的东西工作,我只需要更改
@PlanningEntityCollectionProperty
以便它返回具体类型而不是接口;例如:
@Override
@PlanningEntityCollectionProperty
@ValueRangeProvider(id = "vrpName")
public List<ImplementationEntity> getEntities() {
return super.getLinks();
}
最后,如果你读到这篇文章,请致 OptaPlanner 开发人员:我一直不清楚继承如何与 OptaPlanner 交互。其中大部分是直截了当的,但也有相当数量的“猜测和检查”。我敢肯定,如果 OptaPlanner 文档有更多关于继承的信息,我将不胜感激。实体类等
OptaPlanner 的版本策略是小更新会带来变化和弃用,但不会实际上做出重大改变。事实上,我们确实会定期弃用 API——但我们不会删除它们,因此即使您使用已弃用的东西,一切都应该仍然有效。
你所描述的似乎是一个错误,绝对不是故意的。如果你提供一个最小的复制器,我可以在我的机器上运行来演示这个问题,我会调查它。