从VRP中移除车辆

时间:2015-03-20 14:21:20

标签: optaplanner

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

到目前为止,我已经尝试

  • 在删除车辆之前重置nextCustomer
  • 重置nextCustomer of vehicle和prevStandstill of first first customer
  • 为车辆上的所有链式客户做同样的事情
  • 通过客户名单蛮力

我收到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正常工作并避免例外。但是,这不好吗?

1 个答案:

答案 0 :(得分:1)

做所有这些:

  • 在该车辆的每个nextCustomer中,将该客户的previousStandstill(= var)设置为null,并且它的nextCustomer(=逆阴影变量)也为null,并且&& #39; s vehicle(=锚影变量)也在null。
  • 从解决方案的车辆列表中删除车辆

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

该车辆的客户将被取消初始化,解算器的CH将对其进行初始化。