Java ChainedSwapMove希望链接额外的计划变量(当它来自CountableValueRange<;Long>;)

Java ChainedSwapMove希望链接额外的计划变量(当它来自CountableValueRange<;Long>;),java,optaplanner,Java,Optaplanner,我正在使用Optaplanner 7.38.0.Final 我实现了一个相对简单的模型,遇到了一些问题 我有一个名为“访问”的规划实体,其中有一个规划变量previousStandstill,该变量与车辆路径示例的模式几乎相同,锚变量是“Motorcycle”类,因此基本上优化问题是找到给定摩托车员工的访问链(在第一次创建解决方案时固定)最大限度地缩短所有员工的所有路线时间,并为所有访问提供服务 问题是,我希望不时地断开链以返回仓库,我认为创建另一个类来断开链是不必要的,当需要重新启动路线时,我

我正在使用Optaplanner 7.38.0.Final

我实现了一个相对简单的模型,遇到了一些问题

我有一个名为“访问”的规划实体,其中有一个规划变量
previousStandstill
,该变量与车辆路径示例的模式几乎相同,锚变量是“Motorcycle”类,因此基本上优化问题是找到给定摩托车员工的访问链(在第一次创建解决方案时固定)最大限度地缩短所有员工的所有路线时间,并为所有访问提供服务

问题是,我希望不时地断开链以返回仓库,我认为创建另一个类来断开链是不必要的,当需要重新启动路线时,我包括一个带有历元秒时间戳的计划变量(时间戳在相对较小的范围内,
startOfTrip
在下面的代码中)

Optaplanner能够使用给定的xml配置创建解算器,如果我在分数计算器上创建断点,我可以检查变量,并查看构造启发式能够创建有效的访问链,甚至可以设置时间戳变量的值

但不知何故,几毫秒后,当在第43行调用
org.optaplanner.core.impl.heuristic.selector.move.generic.chained.ChainedSwapMove
构造函数时,解算器会遇到
NullPointerException

public ChainedSwapMove(列表变量描述符列表,
List inverseVariableSupplyList、Object leftEntity、Object rightEntity){
super(variableDescriptorList、leftEntity、rightEntity);
oldLeftTrailingEntityList=新的ArrayList(inverseVariableSupplyList.size());
oldRightTrailingEntityList=新的ArrayList(inverseVariableSupplyList.size());
适用于(单音VersevariableSupply inverseVariableSupply:inverseVariableSupply列表){
oldLeftTrailingEntityList.add(inverseVariableSupply.getInverseSingleton(leftEntity));
oldRightTrailingEntityList.add(inverseVariableSupply.getInverseSingleton(rightEntity));
}
}
变量
inverseVariableSupplyList
似乎包含一个空引用(它在分析包含常规非链式规划变量的variableDescriptorList时创建此空引用)

X包;
导入org.optaplanner.core.api.domain.entity.PlanningEntity;
导入org.optaplanner.core.api.domain.variable.AnchorShadowVariable;
导入org.optaplanner.core.api.domain.variable.InverseRelationShadowVariable;
导入org.optaplanner.core.api.domain.variable.PlanningVariable;
导入org.optaplanner.core.api.domain.variable.PlanningVariableGraphType;
导入javax.persistence.Transient;
导入java.io.Serializable;
导入java.time.LocalDateTime;
@规划实体
公共类OptimizingVisit实现了OptimizingStandstill,可序列化{
私有静态最终长serialVersionUID=9163651541108883957L;
私有连续分支解决方案;
私人秩序;
私人长途旅行;
私人长期启动;
私人长时间到达;
私人长尾;
私人长途旅行;
私人长途旅行;
私有优化暂停以前的暂停;
private OptimizingVisite nextStandstill;//阴影变量
私有优化驱动程序优化驱动程序;
公共优化访问(){
}
公共优化访问(订单、连续分支解决方案){
这个。顺序=顺序;
这个解决方案=解决方案;
}
公共秩序{
退货单;
}
公共无效订单(订单){
这个。顺序=顺序;
}
@AnchorShadowVariable(sourceVariableName=“previousStandstill”)
公共优化驱动程序getOptimizingDriver(){
返回优化驱动程序;
}
公共无效设置优化驱动程序(优化驱动程序优化驱动程序){
this.optimizingDriver=optimizingDriver;
}
公共雇员getDriver(){
返回这个.getOptimizingDriver().getDriver();
}
@计划变量(valueRangeProviderRefs=“startTimeCandidates”)
公共长getStartOfTrip(){
返回startOfTrip;
}
公共无效设置起始OFTRIP(长起始行程){
this.startOfTrip=startOfTrip;
}
公共长期访问期限(){
返回时间;
}
公共无效设置travelDuration(长travelDuration){
this.travelDuration=travelDuration;
}
公共长期旅行立场(){
返回行程;
}
公共旅行距离(长途旅行距离){
这个。旅行距离=旅行距离;
}
@PlanningVariable(graphType=PlanningVariableGraphType.CHAINED,valueRangeProviderRefs={“visitsRange”,“driversRange”})
公共优化暂停getPreviousStandstill(){
返回先前的静止状态;
}
公共无效设置previousStandstill(优化StandStill previousStandstill){
this.previousstandstation=previousstandstation;
}
@凌驾
公共优化访问getNextStandstill(){
返回下一个静止状态;
}
@凌驾
public void setNextStandstill(优化访问nextStandstill){
this.nextstandstal=nextstandstal;
}
@凌驾
公共六边形getHexagon(){
返回此.getOrder().getShippingAddress().getHexagon();
}
公共时间范围getTimeRange(){
返回新的时间范围(this.start、this.end);
}
/*辅助方法*/
公共长getRecursiveStart(){
如果(this.getStartOfTrip()!=null)返回此.getStartOfTrip()+5*60;
如果(this.start!=null)返回this.start;
this.start=this.getPreviousStandstill().getRecursive