我有一个 @PlanningSolution
类,其中一个字段的类型为自定义 List
实现。
解决时我遇到了以下问题(如 optaplanner 文档中所述):
java.lang.IllegalStateException
:为 originalCollectionClass(类 class java.util.ArrayList
)创建的 cloneCollectionClass (Solution$1
) 不可分配给字段的类型 (class CustomListImpl
)。
也许可以考虑替换默认的 SolutionCloner
。
由于此字段对规划没有影响,我是否可以阻止 FieldAccessingSolutionCloner
尝试克隆该特定字段,例如通过添加一些注释?我不想提供完整的自定义 SolutionCloner
。
在检查 FieldAccessingSolutionCloner
的来源时,我发现我只需要覆盖 retrieveCachedFields(...)
或 constructCloneCollection(...)
方法,所以我尝试扩展 FieldAccessingSolutionCloner
但后来我需要一个公共无参数构造函数。我不知道如何在 no-args-constructor 中初始化字段 solutionDescriptor
以使用我的 ExtendedFieldAccessingSolutionCloner
作为解决方案克隆器。
答案 0 :(得分:1)
如果通用解决方案克隆器决定克隆该 List
,那么这样做可能有充分的理由:该列表中的元素之一可能引用了规划实体或规划解决方案 -因此需要计划克隆整个列表。
如果不是这样,这是 OptaPlanner 中的一个错误。请提供带有该字段的类的类源代码以及 CustomListImpl 类,以便我们可以重现和修复它。
要提供自定义 SolutionCloner
,请按照将显示类似内容的文档进行操作(但这是一个没有链接变量的简单案例,因此很容易正确,但解决方案克隆是出了名的困难!)。< /p>
@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());
}
}