For my planning problem with one real planning entity class I need to declare various PriorityQueue
s in one of the problem classes.
However, I'm getting following error message:
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.
So it seems that PriorityQueue
is not cloned as a PriorityQueue by default, but replaced by an ArrayList
by the default cloner.
The manual says
When the FieldAccessingSolutionCloner clones one of your collections or maps, it may not recognize the implementation and replace it with ArrayList, LinkedHashSet, TreeSet, LinkedHashMap or TreeMap (whichever is more applicable) . It recognizes most of the common JDK collection and map implementations.
So PriorityQueue
is not in the 'most common JDK collection ... implementations.' Fine, it's not even a Collection
.
There are three possible solutions to my problem:
PriorityQueue
s in a custom VariableListener
(one PriorityQueue
per planning fact, e.g. in a Map), then make sure the VariableListener
is triggered properlyArrayList
and just sort the Array (e.g., Arrays.sort(pq.toArray())
) as required in my custom VariableListener
SolutionCloner
as suggested by the error message. I don't really want to write one from scratch, I'd prefer just to extend the custom cloner.And here are my two questions:
Thank you in advance!
PriorityQueue
is a collection - I'd argue that cloning queues is something we should fix in the default cloner directly. Looking at the source code, we even support cloning Deque
s. That said, before we fix it:
ArrayList
may be simple enough, assuming the overhead of sorting isn't too much.ai.timefold.solver.core.api.domain.solution.cloner.SolutionCloner
is what you have to implement.The variable listener approach seems like the most correct thing to do - but I wonder what it is that you're doing. Having to "declare various PriorityQueues in one of the problem classes" sounds suspicious - problem facts must be immutable, otherwise trouble will ensue.