Reputation: 1934
I am implementing a custom cloner for the vrp problem.
The docs outline the following:
Cloning an entity with a chained variable is devious: a variable of an entity A might point to another entity B. If A is cloned, then its variable must point to the clone of B, not the original B.
So if we are cloning a Customer
with planning variable previousStandstill
we need to do something like:
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;
}
with Vehicle.safeClone()
Vehicle clonedVehicle = new Vehicle(<CONSTRUCTOR_ARGS>);
// clone shadow variables ?
clonedVehicle.setNextCustomer(customer.safeClone);
However the example above does not work as a cloned solution is not identical anymore. Any pointers in how to safely clone a chained planning entity ? Do I need to deep clone its planning variable ? And what to do with shadow variables ? Do these also need to be deep cloned ?
Upvotes: 0
Views: 126
Reputation: 27312
Classes wise, you need to planning clone every instance that is of a class that has or inherits a @PlanningEntity
(regardless if it's a genuine or shadow entity) or @PlanningSolution
class annotation. The goal is to remember the state of the best solution while the working solution changes. Usually all other classes don't need to be planning cloning normally (but there are exceptions).
So in VRP, that means planning clone VehicleRoutingSolution, Standstill, Vehicle and Customer. But not Depot nor Location.
Then 2 pitfalls to take into account for the relations:
The best way to validate these pitfalls is to put a breakpoint at the end of your cloner and compare the memory address numbers between the working solution and its planing clone for every Customer, Vehicle, etc. IntelliJ shows the memory addresses in gray in the Debug dock's Variables window.
That being said, don't do custom planning cloning. Use @DeepPlanningClone
if you're doing it due to correctness. Wait for OptaPlanner-Kogito to generate a custom cloner if you're doing it for performance or Graal.
Upvotes: 1