Description of problem: consider chain before move: 1 -> 2 -> 3 -> 4 -> 5 and after move: 1 -> 3 -> 4 -> 2 -> 5 and planner log something like: Move index (0), score (-30000), accepted (true), move (2(after 1) => 4(after 3)). which may be wrong, I suppose move should look like: (2(after 1) => 2(after 6)) It is not big issue or something, but some users might be confused by this as me today while working on nearby selection.
Presuming that in your description "->" means before, then the log is correct: We start with 1 before 2 before 3 before 4 before 5 First take take out 2: 1 (before 2) before 3 before 4 before 5 1 before 3 before 4 before 5 then insert it between 4 and 5 1 before 3 before 4 () before 5 1 before 3 before 4 (before 2) before 5 We end with 1 before 3 before 4 before 2 before 5 So, what did we do? - We moved entity 2. - Which had a previousStandstill of 1 (because it 2 was after 1) - And we changed the previousStandstill to 4 (because it ends up after 4). So we had a ChangeMove of entity 2 to toPlanningValue 4, which is exactly what the original log is. A log that states that 2 would move after 2, is impossible btw: as that would violate chaining principles.
Hi, now I see that I have mistake in BZ. There should be obviously "(2(after 1) => 2(after 4))". My point was to have one common entity in both sides of move. From "(2(after 1) => 2(after 4))" I would understand much easier, that we took entity 2 and moved it from behind entity 1 after entity 4 (which is true). So the change has been tracked from point of view entity 2. String "(2(after 1) => 4(after 3))" I intuitively read as "we have entity 2 after 1 and it has been chaned on 4 entity after 3", which is also correct, but state 4 after 3 was here even before our move.
The possibly confusing log message stems from the fact that - ChangeMove.toString() returns entity.toString + " => " toValue.toString() - both entity and toValue are an instance of Visit - Visit.toString() returns id + "(after " + previous.id + ")" Maybe we should have entity.toString() not mention it's planning variable's value and have ChangeMove also mention the original value...
We're discussing about using better toStrings() for the generic moves, so the entities and values can just toString() what makes them unique - and not their state. After: ChangeMove: Process-40 {Computer-X => Computer-Y} SwapMove: Process-40 {Computer-X} <=> Process-50 {Computer-Y} PillarChangeMove: [Process-40, Process-41] {Computer-X => Computer-Y} PillarSwapMove: [Process-40, Process-41] {Computer-X} <=> [Process-50, Process-51] {Computer-Y}
Fixed for OptaPlanner 6.3.0.Beta1. https://github.com/droolsjbpm/optaplanner/commit/4919b1594fa9639aa08855d654100497254e7a78 Not yet backported to 6.2.x, so not in BRMS 6.1. New notations: ChangeMove: "a {v1 -> v2}" SwapMove: "a {v1} <-> b {v2}" PillarChangeMove: "[a, b] {v1 -> v2}" PillarSwapMove: "[a, b] {v1} <-> [c, d, e] {v2}" TailChainSwapMove: "a3 {a2} <-tailChainSwap-> b1 {b0}" SubChainChangeMove: "[a2..a5] {a1 -> b0}" Reversing: "[a2..a5] {a1 -reversing-> b0}" SubChainSwapMove: "[a2..a5] {a1} <-> [b1..b3] {b0}" Reversing: "[a2..a5] {a1} <-reversing-> [b1..b3] {b0}"
Verified