Java Optaplanner将客户从工作VRP解决方案中移除
基于此,我尝试了以下方法:Java Optaplanner将客户从工作VRP解决方案中移除,java,optaplanner,Java,Optaplanner,基于此,我尝试了以下方法: public void doFactChange() { Location toBeRemovedLocation = customerToBeRemoved.getLocation(); Location lookUpWorkingObject = (Location) scoreDirector.lookUpWorkingObject(toBeRemovedLocation); scoreDirector.beforeProblemFact
public void doFactChange() {
Location toBeRemovedLocation = customerToBeRemoved.getLocation();
Location lookUpWorkingObject = (Location) scoreDirector.lookUpWorkingObject(toBeRemovedLocation);
scoreDirector.beforeProblemFactRemoved(lookUpWorkingObject);
routingSolution.getLocationList().remove(lookUpWorkingObject);
scoreDirector.afterProblemFactRemoved(lookUpWorkingObject);
Customer workingCustomer = (Customer) scoreDirector.lookUpWorkingObject(customerToBeRemoved);
for (Customer customer : routingSolution.getCustomerList()) {
while (customer != null) {
if (customer == workingCustomer) {
if (customer.getPreviousStandstill() != null) {
scoreDirector.beforeVariableChanged(customer, "previousStandstill");
customer.getPreviousStandstill().setNextCustomer(customer.getNextCustomer());
scoreDirector.afterVariableChanged(customer, "previousStandstill");
}
scoreDirector.beforeVariableChanged(customer, "nextCustomer");
customer.getNextCustomer().setPreviousStandstill(customer.getPreviousStandstill());
scoreDirector.afterVariableChanged(customer, "nextCustomer");
}
customer = customer.getNextCustomer();
}
}
scoreDirector.beforeEntityRemoved(workingCustomer);
routingSolution.getCustomerList().remove(workingCustomer);
scoreDirector.afterEntityRemoved(workingCustomer);
scoreDirector.triggerVariableListeners();
}
注意:customerToBeRemoved
是在调用doFactChange()之前创建的实例对象
但我甚至在调用scoreDirector.triggerVariableListeners
java.lang.IllegalStateException:实体(Customer--9048381398840634905)有一个值为(Customer--9070671076516032025)的变量(previousStandstill),该变量有一个值为(Customer-8518512081385427431)的sourceVariableName变量(nextCustomer),该值不是该实体。
验证该sourceVariableName变量的输入问题的一致性
另一个问题:
我尝试直接删除实体,如下所示:
public void doFactChange() {
Location toBeRemovedLocation = customerToBeRemoved.getLocation();
Location lookUpWorkingObject = (Location) scoreDirector.lookUpWorkingObject(toBeRemovedLocation);
scoreDirector.beforeProblemFactRemoved(lookUpWorkingObject);
routingSolution.getLocationList().remove(lookUpWorkingObject);
scoreDirector.afterProblemFactRemoved(lookUpWorkingObject);
Customer workingCustomer = (Customer) scoreDirector.lookUpWorkingObject(customerToBeRemoved);
scoreDirector.beforeEntityRemoved(workingCustomer);
routingSolution.getCustomerList().remove(workingCustomer);
scoreDirector.afterEntityRemoved(workingCustomer);
scoreDirector.triggerVariableListeners();
}
这有效吗?此方法适用于optaplanner VRP示例,使用简单、递增和drl分数计算器:
public void removeRandomCustomer()
{
doProblemFactChange(scoreDirector -> {
VehicleRoutingSolution solution = scoreDirector.getWorkingSolution();
int rnd = 4; //select a random customer
if (solution.getCustomerList().size() > rnd)
{
Customer customer = solution.getCustomerList().get(rnd);
scoreDirector.beforeEntityRemoved(customer);
removeCustomer(solution, customer);
scoreDirector.afterEntityRemoved(customer);
scoreDirector.triggerVariableListeners();
}
});
}
private void removeCustomer(VehicleRoutingSolution solution, Customer customer)
{
Standstill anchor = customer.getPreviousStandstill();
Customer nextCustomer = customer.getNextCustomer();
//anchor shouldn't be null in an initialized solution
if (anchor != null)
anchor.setNextCustomer(nextCustomer);
if (nextCustomer != null)
nextCustomer.setPreviousStandstill(anchor);
solution.getCustomerList().remove(customer);
}
编辑:
具有简易/增量评分的影子变量替代方法:
private void removeCustomer(ScoreDirector<VehicleRoutingSolution> scoreDirector, VehicleRoutingSolution solution, Customer removeCustomer)
{
final Customer customer = scoreDirector.lookUpWorkingObject(removeCustomer);
Standstill anchor = customer.getPreviousStandstill();
Customer nextCustomer = customer.getNextCustomer();
//scoreDirector.beforeVariableChanged(anchor, "nextCustomer");
scoreDirector.beforeVariableChanged(customer, "previousStandstill"); //sets anchor.nextCustomer=null
customer.setPreviousStandstill(null);
scoreDirector.afterVariableChanged(customer, "previousStandstill");
//scoreDirector.afterVariableChanged(anchor, "nextCustomer");
if(nextCustomer!=null)
{
//scoreDirector.beforeVariableChanged(customer, "nextCustomer");
scoreDirector.beforeVariableChanged(nextCustomer, "previousStandstill"); //sets customer.nextCustomer=null
nextCustomer.setPreviousStandstill(anchor);
scoreDirector.afterVariableChanged(nextCustomer, "previousStandstill");
//scoreDirector.afterVariableChanged(customer, "nextCustomer");
}
scoreDirector.beforeEntityRemoved(customer);
//clone customer list
ArrayList<Customer> changedList = new ArrayList<>(solution.getCustomerList());
solution.setCustomerList(changedList);
solution.getCustomerList().remove(customer);
scoreDirector.afterEntityRemoved(customer);
scoreDirector.triggerVariableListeners(); //sets customer.vehicle=null, sets all nextCustomer.vehicle=null
}
private void remove客户(ScoreDirector ScoreDirector,车辆路线解决方案,客户移除客户)
{
最终客户=scoreDirector.lookUpWorkingObject(removeCustomer);
Standstill anchor=customer.getPreviousStandstill();
Customer-nextCustomer=Customer.getNextCustomer();
//scoreDirector.beforeVariableChanged(锚定,“下一个客户”);
scoreDirector.beforeVariableChanged(customer,“previousStandstill”);//设置anchor.nextCustomer=null
customer.setPreviousStandstill(空);
scoreDirector.afterVariableChanged(客户,“以前的停止”);
//scoreDirector.afterVariableChanged(锚定,“下一个客户”);
if(nextCustomer!=null)
{
//scoreDirector.beforeVariableChanged(客户,“下一个客户”);
scoreDirector.beforeVariableChanged(nextCustomer,“previousStandstill”);//设置customer.nextCustomer=null
下一个客户设置上一个停止(锚);
scoreDirector.afterVariableChanged(下一个客户,“以前的停滞”);
//scoreDirector.afterVariableChanged(客户,“下一个客户”);
}
scoreDirector.在实体移除之前(客户);
//克隆客户列表
ArrayList changedList=新的ArrayList(solution.getCustomerList());
解决方案.setCustomerList(changedList);
solution.getCustomerList().remove(客户);
scoreDirector.afterEntityRemoved(客户);
scoreDirector.triggerVariableListeners();//设置customer.vehicle=null,设置所有nextCustomer.vehicle=null
}
解决方案现在应该处于有效状态,但您可能必须修复增量计分(轻松计分很好,因为doProblemFactChange()
会自动重新计算它),可能需要删除VehiclerOutingIncrementalCoreCalculator.beforeEntityRemoved()
中的收回。如果其他所有操作都失败,您可以首先将客户移动到链的末端并将其移除。@Geoffrey De Smet,您的支持人员。如果不工作,则会出现以下异常:java.lang.IllegalStateException:entity(customer--9070677347168284185)有一个值为(customer--9097931491641785)的变量(以前的静止状态)其sourceVariableName变量(nextCustomer)的值(null)不是该实体。验证sourceVariableName变量的输入问题的一致性。这有点奇怪。您是否更改了其他内容,可能是在doProblemFactChange()
方法中?发布的代码使用optaplanner-Distribution-7.5.0.Final中的VRP示例进行了测试,它与正在运行和停止的解算器一起工作。它如何在没有调用scoreDirector上的beforeVariableChanged和afterVariableChanged的情况下工作?我怀疑Grudolf的方法是正确的,但是Java播放器的IllegalStateException是他之前添加的另一个复杂性,这意味着remoteCustomer不能盲目复制粘贴(或者它也可能是存在的、不相关的无效状态)。好的Geoffrey,如果我们忽略该异常并查看该方法的结构,它有什么问题?