我正在为vrp问题实现自定义克隆器。
文档概述了以下内容:
使用链接的变量对实体进行克隆是不正确的:实体A的变量可能指向另一个实体B。如果克隆了A,则其变量必须指向B的克隆,而不是原始B。
因此,如果我们要使用计划变量Customer
克隆previousStandstill
,则需要执行以下操作:
public Customer safeClone() {
Customer clonedCustomer = new Customer(<CONSTRUCTOR_ARGS>);
if (previousStandstill != null) {
if (previousStandstill instanceof Vehicle) {
clonedCustomer.setPreviousStandstill( ((Vehicle)previousStandstill).safeClone();
} else if (previousStandstill instanceof Customer) {
clonedCustomer.setPreviousStandstill( ((Customer)previousStandstill).safeClone();
}
}
// What to do with shadow variables ?
return clonedCustomer;
}
与Vehicle.safeClone()
Vehicle clonedVehicle = new Vehicle(<CONSTRUCTOR_ARGS>);
// clone shadow variables ?
clonedVehicle.setNextCustomer(customer.safeClone);
但是,以上示例由于克隆的解决方案不再有效,因此不再适用。关于如何安全克隆链式计划实体的任何指示?我是否需要深克隆其计划变量?影子变量该怎么办?这些还需要深度克隆吗?
答案 0 :(得分:1)
明智地使用类,您需要计划克隆具有或继承@PlanningEntity
(无论是真实实体还是影子实体)或@PlanningSolution
类注释的类的每个实例。目的是在工作解决方案更改时记住最佳解决方案的状态。通常,所有其他类都不需要正常计划克隆(但是有例外)。
因此在VRP中,这意味着计划克隆VehicleRoutingSolution,Standstill,Vehicle和Customer。但不是仓库也不是位置。
然后要考虑两种关系的陷阱:
验证这些陷阱的最佳方法是在克隆程序的末尾放置一个断点,并比较每个客户,车辆等在工作解决方案及其计划克隆之间的内存地址号。IntelliJ以灰色显示内存地址在“调试”扩展坞的“变量”窗口中。
话虽如此,请勿进行自定义计划克隆。由于正确性,请使用@DeepPlanningClone
。如果您出于性能或Graal的目的,请等待OptaPlanner-Kogito生成自定义克隆。