Optaplanner:防止自定义列表被 FieldAccessingSolutionCloner 克隆

Optaplanner: prevent custom List from beeing cloned by FieldAccessingSolutionCloner

我有一个 @PlanningSolution class,它有一个字段以自定义 List 实现作为类型。 当我 运行 解决以下问题时(如 optaplanner 文档中所述):

java.lang.IllegalStateException: 为 originalCollectionClass (class Solution) 创建的 cloneCollectionClass (class java.util.ArrayList) 不可分配给字段的类型 (class CustomListImpl). 也许考虑更换默认的 SolutionCloner.

由于该字段对规划没有影响,我可以阻止 FieldAccessingSolutionCloner 尝试克隆该特定字段吗?通过添加一些注释?我不想提供完整的自定义 SolutionCloner.

在检查 FieldAccessingSolutionCloner 的来源时,我发现我只需要重写方法 retrieveCachedFields(...)constructCloneCollection(...) 所以我尝试扩展 FieldAccessingSolutionCloner 但后来我需要一个 public 无参数构造函数。我不知道如何在无参数构造函数中初始化字段 solutionDescriptor 以将我的 ExtendedFieldAccessingSolutionCloner 用作解决方案克隆器。

如果通用解决方案克隆者决定克隆那个 List,这样做可能有充分的理由:该列表中的元素之一可能引用了规划实体或规划解决方案 - 因此需要计划克隆整个列表。

如果不是这样,这是 OptaPlanner 中的错误。请提供带有该字段的 class 的 classes 源代码和 CustomListImpl class,以便我们可以重现和修复它。


要提供自定义 SolutionCloner,请按照将显示类似内容的文档进行操作(但这是一个没有链式变量的简单案例,因此很容易正确,但解决方案克隆是出了名的困难!) .

@PlanningSolution(solutionCloner = VaccinationSolutionCloner.class)
public class VaccinationSolution {...}


public class VaccinationSolutionCloner implements SolutionCloner<VaccinationSolution> {

    @Override
    public VaccinationSolution cloneSolution(VaccinationSolution solution) {
        List<PersonAssignment> personAssignmentList = solution.getPersonAssignmentList();
        List<PersonAssignment> clonedPersonAssignmentList = new ArrayList<>(personAssignmentList.size());
        for (PersonAssignment personAssignment : personAssignmentList) {
            PersonAssignment clonedPersonAssignment = new PersonAssignment(personAssignment);
            clonedPersonAssignmentList.add(clonedPersonAssignment);
        }
        return new VaccinationSolution(solution.getVaccineTypeList(), solution.getVaccinationCenterList(), solution.getAppointmentList(),
                solution.getVaccinationSlotList(), clonedPersonAssignmentList, solution.getScore());
    }

}