从 VRP 中删除车辆

Remove a vehicle from VRP

通过 ProblemFactChange 从规划实体集合中移除(=删除)车辆的正确方法是什么(类似于 OptaPlanner VRP 示例中的 VehicleRoutingSolution.VehicleList)?

到目前为止我已经尝试过

我收到 IllegalStateException,要么是因为 prevStandstill 和 nextCustomer 之间不匹配,要么是本地搜索阶段因未初始化的解决方案而开始失败。

编辑:将链中的第一个客户转移到另一辆车似乎工作正常。

编辑 2

我尝试使用此代码段重置链中的所有客户

Customer customer = vehicle.getNextCustomer();
while(customer!=null)
{
    Customer nextCustomer = customer.getNextCustomer();
    scoreDirector.beforeVariableChanged(customer, "previousStandstill");    //Exception on second customer
    customer.setPreviousStandstill(null);
    scoreDirector.afterVariableChanged(customer, "previousStandstill");
    scoreDirector.beforeVariableChanged(customer, "nextCustomer");
    customer.setNextCustomer(null);
    scoreDirector.afterVariableChanged(customer, "nextCustomer");
    customer.setVehicle(null);
    customer=nextCustomer;
}

但我在第二个 运行 通过循环

时遇到 IllegalStateException
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: The entity (CUST39(after CUST39)) has a variable (previousStandstill) with value (CUST39(after null)) which has a sourceVariableName variable (nextCustomer) with a value (null) which is not that entity.
Verify the consistency of your input problem for that sourceVariableName variable.
    at org.optaplanner.core.impl.domain.variable.inverserelation.SingletonInverseVariableListener.retract(SingletonInverseVariableListener.java:82)
    at org.optaplanner.core.impl.domain.variable.inverserelation.SingletonInverseVariableListener.beforeVariableChanged(SingletonInverseVariableListener.java:44)
    at org.optaplanner.core.impl.domain.variable.listener.VariableListenerSupport.beforeVariableChanged(VariableListenerSupport.java:145)
    at org.optaplanner.core.impl.score.director.AbstractScoreDirector.beforeVariableChanged(AbstractScoreDirector.java:257)
    at org.optaplanner.core.impl.score.director.AbstractScoreDirector.beforeVariableChanged(AbstractScoreDirector.java:228)

看起来很明显(状态无效,因为第一个客户与第二个客户分离,但第二个客户仍然指向第一个客户),但我不知道正确的路线是什么;)绕过它。

这个

    Customer nextCustomer = customer.getNextCustomer();
    customer.setPreviousStandstill(null);
    customer.setNextCustomer(null);
    scoreDirector.beforeVariableChanged(customer, "previousStandstill");
    scoreDirector.beforeVariableChanged(customer, "nextCustomer");
    scoreDirector.afterVariableChanged(customer, "nextCustomer");
    scoreDirector.afterVariableChanged(customer, "previousStandstill");

似乎工作 - CH 为每个被删除的客户被解雇,移动计数正确,EasyScore 工作并且避免了异常。但是,不好吗?

做所有这些:

  • 当该车辆的每个 nextCustomer 时,将该客户的 previousStandstill (= var) 设置为 null,并且它的 nextCustomer (= inverse shadow var) 也设置为 null,并且它是 vehicle ( = 锚影 var) 也为空。
  • 从解决方案的车辆列表中删除车辆

确保正确调用 before/after 方法。

该车辆的客户随后将被取消初始化,求解器的 CH 将初始化他们。