anchor.diff:  [[realTimePlanning]]
   == Real-time Planning
   
  -To do real-time planning, first combine <<backupPlanning,backup planning>> and <<continuousPlanning,continuous planning>> with short planning windows to lower the burden of real-time planning.
  -As time passes, the problem itself changes:
  +To do real-time planning, combine the following planning techniques:
  +
  +* <<backupPlanning,Backup planning>> - adding extra score constraints to allow for unforeseen changes).
  +* <<continuousPlanning,Continuous planning>> - planning for one or more future planning periods.
  +* Short planning windows.
  ++
  +This lowers the burden of real-time planning.
  +
  +As time passes, the problem itself changes. Consider the vehicle routing use case:
   
   image::RepeatedPlanning/realTimePlanningVehicleRouting.png[align="center"]
   
  -In the example above, three customers are added at different times (``07:56``, `08:02` and ``08:45``), after the original customer set finished solving at `07:55` and in some cases after the vehicles already left.
  -Planner can handle such scenario's with `ProblemFactChange` (in combination with <<immovablePlanningEntities,immovable planning entities>>).
  +In the example above, three customers are added at different times (``07:56``, `08:02` and ``08:45``), after the original customer set finished solving at `07:55`, and in some cases, after the vehicles already left.
  +
  +Planner can handle such scenarios with `ProblemFactChange` (in combination with <<immovablePlanningEntities,immovable planning entities>>).
   
   
   [[problemFactChange]]
  -=== `ProblemFactChange`
  -
  -While the `Solver` is solving, an outside event might want to change one of the problem facts, for example an airplane is delayed and needs the runway at a later time.
  -Do not change the problem fact instances used by the `Solver` while it is solving (from another thread or even in the same thread), as that will corrupt it.
  -Instead, add a `ProblemFactChange` to the `Solver` which it will execute in the solver thread as soon as possible.
  +=== ProblemFactChange
  +
  +While the `Solver` is solving, one of the problem facts may be changed by an outside event. For example, an airplane is delayed and needs the runway at a later time.
  +
  +[IMPORTANT]
  +====
  +Do not change the problem fact instances used by the `Solver` while it is solving (from another thread or even in the same thread), as that will corrupt it. 
  +====
  +
  +Add a `ProblemFactChange` to the `Solver`, which it executes in the solver thread as soon as possible. For example:
   
   [source,java,options="nowrap"]
   ----
  
positive.code:     }
  ----
  
  [WARNING]
  ====
  Any change on the problem facts or planning entities in a `ProblemFactChange` must be told to the ``ScoreDirector``.
  ====
  
  image::RepeatedPlanning/realTimePlanningConcurrencySequenceDiagram.png[align="center"]
  
  [IMPORTANT]
  ====
  To write a `ProblemFactChange` correctly, it's important to understand the behaviour of <<cloningASolution,a planning clone>>:
  
  * Any change in a `ProblemFactChange` must be done on the `Solution` instance of ``scoreDirector.getWorkingSolution()``.
  The `workingSolution` is <<cloningASolution,a planning clone>> of the ``BestSolutionChangedEvent``'s ``bestSolution``.
  So the `workingSolution` in the `Solver` is never the same instance as the `Solution` in the rest of your application: it is a planning clone.
  Use the method `ScoreDirector.lookUpWorkingObject()` to translate an retrieve the working solution's instance of an object.
  * A planning clone also clones the planning entities and planning entity collections.
  So any change on the planning entities must happen on the instances hold by ``scoreDirector.getWorkingSolution()``.
  * A planning clone does not clone the problem facts, nor the problem fact collections.
  _Therefore the ``__workingSolution__`` and the ``__bestSolution__`` share the same problem fact instances and the same problem fact list instances._
  + 
  Any problem fact or problem fact list changed by a `ProblemFactChange` must be problem cloned first (which can imply rerouting references in other problem facts and planning entities). Otherwise, if the `workingSolution` and `bestSolution` are used in different threads (for example a solver thread and a GUI event thread), a race condition can occur.
  
  ====
  
  [NOTE]
  ====
  Many types of changes can leave a planning entity uninitialized, resulting in a partially initialized solution.
  That's fine, as long as the first solver phase can handle it.
  All construction heuristics solver phases can handle that, so it's recommended to configure such a solver phase as the first phase.
  ====
  
  In essence, the `Solver` stops, runs the `ProblemFactChange` and **restarts**.
  This is a _warm start_ because its initial solution is the adjusted best solution of the previous run.
  Each solver phase runs again.
  This implies the construction heuristic runs again, but because little or no planning variables are uninitialized (unless you have a <<nullablePlanningVariable,nullable planning variable>>), it finishes much quicker than in a cold start.
  
  Each configured `Termination` resets (both in solver and phase configuration), but a previous call to `terminateEarly()` is not undone.
  Normally however, you won't configure any `Termination` (except in daemon mode), just call `Solver.terminateEarly()` when the results are needed.
  Alternatively, do configure a `Termination` and use the daemon mode in combination with `<<SolverEventListener,BestSolutionChangedEvent>>` as described below.
  
  
  [[daemon]]
  === Daemon: `solve()` Does Not Return
  
  In real-time planning, it's often useful to have a solver thread wait when it runs out of work, and immediately resume solving a problem once new problem fact changes are added.
  Putting the `Solver` in daemon mode has these effects:
  
  * If the ``Solver``'s `Termination` terminates, it does not return from `solve()` but blocks its thread instead (which frees up CPU power).
  ** Except for ``terminateEarly()``, which does make it return from ``solve()``, freeing up system resources and allowing an application to shutdown gracefully.
  ** If a `Solver` starts with an empty planning entity collection, it waits in the blocked state immediately.
  * If a `ProblemFactChange` is added, it goes into the running state, applies the `ProblemFactChange` and runs the `Solver` again.
  
  To configure the daemon mode:
  
  [source,xml,options="nowrap"]
  ----
  <solver>
  
negative.code: }
  ----
  
  
  [WARNING]
  ====
  The `ScoreDirector` must be updated with any change on the problem facts of planning entities in a `ProblemFactChange`.
  ====
  
  
  To write a `ProblemFactChange` correctly, it is important to understand the behavior of <<cloningASolution,a planning clone>>. 
  
  A planning clone of a solution must fulfil these requirements:
  
  * The clone must represent the same planning problem. Usually it reuses the same instances of the problem facts and problem fact collections as the original.
  
  * The clone must use different, cloned instances of the entities and entity collections. Changes to an original Solution entity’s variables must not affect its clone.
  
  
  [[problemFactChangeExample]]
  ==== Cloud Balancing ProblemFactChange Example
  
  Consider the following example of a `ProblemFactChange` implementation in the cloud balancing use case:
  
  
  [source,java,options="nowrap"]
  ----
  