I asked a related question here. And after looking into the construction heuristics and local search step. I find the root cause is that during construction heuristics phase, the planner finds the best solution for the first entity MeetingAssignment, it doesn't violate any hard/medium/soft constraints. And other entities violate different constraints. However, in the next phase of local search, the planner tends not to move this entity anymore. It is fixed, but we could find a better solution if we move the fixed entity to other slots(change the planning variable). All the entities could violate fewer constraints.
I have seen the wiki on customized moves. But to solve it, I don't know how to define the move. The move is only needed if the hard constraints are violated and I'm not sure how to define the move as it is only intended to move a fixed entity with no violations.
I have also thought about different algorithms on construction heuristics. But algorithms like first_fit_decrease or others would require to define a difficulty comparator. But these entities are equal.
Do you have suggestion to solve it?
There are a few out of the box moves you can try in OptaPlanner/Timefold, before writing a custom move.
Typically you want to add a generic or custom move, on top of a normal change and swap move, using a union moves selector.
Writing custom moves is a pain (especially JIT scalable) - we're very well aware of that and we are researching ways to make it a lot easier. That being said, they do wonders for complex use cases that need them.