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());
}
}
我有一个 @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());
}
}