替换默认解决方案克隆器

问题描述 投票:0回答:1

对于一个真实规划实体类的规划问题,我需要在问题类之一中声明各种

PriorityQueue

但是,我收到以下错误消息:

Exception in thread "main" java.lang.IllegalStateException: The cloneCollectionClass (class java.util.ArrayList) created for originalCollectionClass (class java.util.PriorityQueue) is not assignable to the field's type (class java.util.PriorityQueue).
Maybe consider replacing the default SolutionCloner.

所以看来

PriorityQueue
默认情况下并没有克隆为PriorityQueue,而是被默认克隆器替换为
ArrayList

说明书上有说

当 FieldAccessingSolutionCloner 克隆您的集合之一时 或地图,它可能无法识别实现并将其替换为 ArrayList、LinkedHashSet、TreeSet、LinkedHashMap 或 TreeMap(以其中一个为准) 更适用)。它识别大多数常见的 JDK 集合 和地图实现。

所以

PriorityQueue
不在“最常见的 JDK 集合......实现”中。好吧,这甚至不是
Collection

我的问题有三种可能的解决方案:

  1. PriorityQueue
    放入自定义
    VariableListener
    中(每个计划事实一个
    PriorityQueue
    ,例如在地图中),然后确保正确触发
    VariableListener
  2. 不要理会 PriorityQueues,将所有内容转换为
    ArrayList
    ,然后按照我的自定义要求对数组(例如,
    Arrays.sort(pq.toArray())
    )进行排序
    VariableListener
  3. 按照错误消息的建议创建自定义
    SolutionCloner
    。我真的不想从头开始编写一个,我只想扩展自定义克隆器。

这是我的两个问题:

  • 关于上述三个解决方案的偏好有什么提示吗?
  • 自定义克隆器位于何处以及如何开始扩展它?

提前谢谢您!

optaplanner timefold
1个回答
0
投票

PriorityQueue
是一个集合 - 我认为克隆队列是我们应该直接在默认克隆器中修复的东西。查看源代码,我们甚至支持克隆
Deque
。也就是说,在我们修复它之前:

  • 使用
    ArrayList
    可能足够简单,假设排序的开销不是太多。
  • 我不会尝试自己实现克隆,克隆是一件很难正确完成的事情 - 但如果你必须这样做,
    ai.timefold.solver.core.api.domain.solution.cloner.SolutionCloner
    就是你必须实现的。

变量监听器方法似乎是最正确的做法 - 但我想知道你在做什么。必须“在问题类之一中声明各种 PriorityQueues”听起来很可疑 - 问题事实必须是不可变的,否则麻烦就会随之而来。

© www.soinside.com 2019 - 2024. All rights reserved.