Package org.optaplanner.core.impl.heuristic.move

## Interface Move<Solution_>

- Type Parameters:
    `Solution_` - the solution type, the class with the `PlanningSolution` annotation
  All Known Implementing Classes:
    `AbstractMove`, `ChainedChangeMove`, `ChainedSwapMove`, `ChangeMove`, `CompositeMove`, `KOptMove`, `NoChangeMove`, `PartitionChangeMove`, `PillarChangeMove`, `PillarSwapMove`, `SubChainChangeMove`, `SubChainReversingChangeMove`, `SubChainReversingSwapMove`, `SubChainSwapMove`, `SwapMove`, `TailChainSwapMove`

      public interface Move<Solution_>

  A Move represents a change of 1 or more `PlanningVariable`s of 1 or more `PlanningEntity`s in the working `PlanningSolution`.

  Usually the move holds a direct reference to each `PlanningEntity` of the `PlanningSolution` which it will change when `doMove(ScoreDirector)` is called. On that change it should also notify the `ScoreDirector` accordingly.

  A Move should implement `Object.equals(Object)` and `Object.hashCode()` for `MoveTabuAcceptor`.

  An implementation must extend `AbstractMove` to ensure backwards compatibility in future versions.

  See Also:
    `AbstractMove`

- - ### Method Summary

    All Methods Instance Methods Abstract Methods Default Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `Move<Solution_>` | `doMove​(ScoreDirector<Solution_> scoreDirector)` | Does the move (which indirectly affects the `ScoreDirector.getWorkingSolution()`).
    `default Collection<? extends Object>` | `getPlanningEntities()` | Returns all planning entities that are being changed by this move.
    `default Collection<? extends Object>` | `getPlanningValues()` | Returns all planning values that entities are being assigned to by this move.
    `default String` | `getSimpleMoveTypeDescription()` | Describes the move type for statistical purposes.
    `boolean` | `isMoveDoable​(ScoreDirector<Solution_> scoreDirector)` | Called before a move is evaluated to decide whether the move can be done and evaluated.
    `default Move<Solution_>` | `rebase​(ScoreDirector<Solution_> destinationScoreDirector)` | Rebases a move from an origin `ScoreDirector` to another destination `ScoreDirector` which is usually on another `Thread` or JVM.

- - ### Method Detail

    - #### isMoveDoable

          boolean isMoveDoable​(ScoreDirector<Solution_> scoreDirector)

      Called before a move is evaluated to decide whether the move can be done and evaluated. A Move is not doable if:
      - Either doing it would change nothing in the `PlanningSolution`.
      - Either it's simply not possible to do (for example due to built-in hard constraints).

      It is recommended to keep this method implementation simple: do not use it in an attempt to satisfy normal hard and soft constraints.

      Although you could also filter out non-doable moves in for example the `MoveSelector` or `MoveListFactory`, this is not needed as the `Solver` will do it for you.

      Parameters:
        `scoreDirector` - the `ScoreDirector` not yet modified by the move.
      Returns:
        true if the move achieves a change in the solution and the move is possible to do on the solution.

    - #### doMove

          Move<Solution_> doMove​(ScoreDirector<Solution_> scoreDirector)

      Does the move (which indirectly affects the `ScoreDirector.getWorkingSolution()`). When the `working solution` is modified, the `ScoreDirector` must be correctly notified (through `ScoreDirector.beforeVariableChanged(Object, String)` and `ScoreDirector.afterVariableChanged(Object, String)`), otherwise later calculated `Score`s will be corrupted.

      This method must end with calling `ScoreDirector.triggerVariableListeners()` to ensure all shadow variables are updated.

      This method must return an undo move, so the move can be evaluated and then be undone without resulting into a permanent change in the solution.

      Parameters:
        `scoreDirector` - never null, the `ScoreDirector` that needs to get notified of the changes
      Returns:
        an undoMove which does the exact opposite of this move

    - #### rebase

          default Move<Solution_> rebase​(ScoreDirector<Solution_> destinationScoreDirector)

      Rebases a move from an origin `ScoreDirector` to another destination `ScoreDirector` which is usually on another `Thread` or JVM. The new move returned by this method translates the entities and problem facts to the destination `PlanningSolution` of the destination `ScoreDirector`, That destination `PlanningSolution` is a deep planning clone (or an even deeper clone) of the origin `PlanningSolution` that this move has been generated from.

      That new move does the exact same change as this move, resulting in the same `PlanningSolution` state, presuming that destination `PlanningSolution` was in the same state as the original `PlanningSolution` to begin with.

      Generally speaking, an implementation of this method iterates through every entity and fact instance in this move, translates each one to the destination `ScoreDirector` with `ScoreDirector.lookUpWorkingObject(Object)` and creates a new move instance of the same move type, using those translated instances.

      The destination `PlanningSolution` can be in a different state than the original `PlanningSolution`. So, rebasing can only depend on the identity of `planning entities` and planning facts, which is usually declared by a `PlanningId` on those classes. It must not depend on the state of the `planning variables`. One thread might rebase a move before, amid or after another thread does that same move instance.

      This method is thread-safe.

      Parameters:
        `destinationScoreDirector` - never null, the `ScoreDirector.getWorkingSolution()` that the new move should change the planning entity instances of.
      Returns:
        never null, a new move that does the same change as this move on another solution instance

    - #### getSimpleMoveTypeDescription

          default String getSimpleMoveTypeDescription()

      Describes the move type for statistical purposes. For example "ChangeMove(Process.computer)".

      The format is not formalized. Never parse the `String` returned by this method.

      Returns:
        never null

    - #### getPlanningEntities

          default Collection<? extends Object> getPlanningEntities()

      Returns all planning entities that are being changed by this move. Required for `AcceptorType.ENTITY_TABU`.

      This method is only called after `doMove(ScoreDirector)` (which might affect the return values).

      Duplicate entries in the returned `Collection` are best avoided. The returned `Collection` is recommended to be in a stable order. For example: use `List` or `LinkedHashSet`, but not `HashSet`.

      Returns:
        never null

    - #### getPlanningValues

          default Collection<? extends Object> getPlanningValues()

      Returns all planning values that entities are being assigned to by this move. Required for `AcceptorType.VALUE_TABU`.

      This method is only called after `doMove(ScoreDirector)` (which might affect the return values).

      Duplicate entries in the returned `Collection` are best avoided. The returned `Collection` is recommended to be in a stable order. For example: use `List` or `LinkedHashSet`, but not `HashSet`.

      Returns:
        never null