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: :icons: font
  :experimental:
  
  
  [[introductionToRepeatedPlanning]]
  == Introduction to Repeated Planning
  
  The world constantly changes.
  The problem facts used to create a solution, might change before or during the execution of that solution.
  There are different situations (which can be combined):
  
  * __Unforeseen fact changes__: For example: an employee assigned to a shift calls in sick, an airplane scheduled to take off has a technical delay, one of the machines or vehicles break down, ... Use **backup planning**.
  * __Impossible to assign all entities now__: Leave some unassigned. For example: there are 10 shifts at the same time to assign but only nine employees to handle shifts. Use **overconstrained planning**.
  * __Unknown long term future facts__: For example: The hospital admissions for the next two weeks are reliable, but those for week three and four are less reliable and for week five and beyond are not worth planning yet. Use **continuous planning**.
  * __Constantly changing problem facts__: Use **real-time planning**.
  
  Waiting to start planning - to lower the risk of problem facts changing - usually isn't a good way to deal with that.
  More CPU time means a better planning solution.
  An incomplete plan is better than no plan.
  
  Luckily, the optimization algorithms support planning a solution that's already (partially) planned, known as repeated planning.
  
  
  [[backupPlanning]]
  == Backup Planning
  
  Backup planning is the technique of adding extra score constraints to create space in the planning for when things go wrong.
  That creates a backup plan in the plan.
  For example: try to assign an employee as the spare employee (one for every 10 shifts at the same time), keep one hospital bed open in each department, ...
  
  Then, when things go wrong (one of the employees calls in sick), change the problem facts on the original solution (delete the sick employee leave his/her shifts unassigned) and just restart the planning, starting from that solution, which has a different score now.
  The construction heuristics will fill in the newly created gaps (probably with the spare employee) and the metaheuristics will even improve it further.
  
  
  [[overconstrainedPlanning]]
  == Overconstrained Planning
  
  When there is no feasible solution to assign all planning entities, it's often desired to assign as many entities as possible without breaking hard constraints.
  This is called overconstrained planning.
  
  By default, Planner will assign all planning entities, overload the planning values and therefore break hard constraints.
  There are two ways to avoid that:
  
  * Use <<nullablePlanningVariable,nullable>> planning variables, so some entities are unassigned.
  * Add virtual values to catch the unassigned entities.
  
  
  
negative.code: 
  To implement this:
  
  . Add an additional score level (usually a medium level between the hard and soft level) by switching <<scoreType,`Score` type>>.
  . Make the planning variable <<nullablePlanningVariable,nullable>>.
  . Add a score constraint on the new level (usually a medium constraint) to penalize the number of unassigned entities (or a weighted sum of them).
  
  
  [[overconstrainedPlanningWithVirutalValues]]
  === Overconstrained Planning with Virtual Values
  
  In overconstrained planning it is often useful to know which resources are lacking.
  In overconstrained planning with virtual values, the solution indicates which resources to buy.
  
  To implement this:
  
  . Add an additional score level (usually a medium level between the hard and soft level) by switching <<scoreType,`Score` type>>.
  . Add a number of virtual values. It can be difficult to determine a good formula to calculate that number:
  ** Do not add too many, as that will decrease solver efficiency.
  ** Importantly, do not add too few as that will lead to an infeasible solution.
  . Add a score constraint on the new level (usually a medium constraint) to penalize the number of virtual assigned entities (or a weighted sum of them).
  . Optionally, change all soft constraints to ignore virtual assigned entities.
  
  [[continuousPlanning]]
  == Continuous Planning (Windowed Planning)
  
  Continuous planning is the technique of planning one or more upcoming planning periods at the same time and repeating that process monthly, weekly, daily, hourly, or even more frequently.
  However, as time is infinite, planning all future time periods is impossible.
  
  A planning window allows you to have a fixed number of upcoming planning time periods.
  
  The planning window can be split up in several parts:
  
  * _History_ 
  +
  Immutable past time periods. It contains only immovable entities.
  +
  ** Historic entities can also affect score constraints that apply to movable entities. For example, in nurse rostering, a nurse that has worked the last five historic days in a row should not be assigned on the first tentative day of the planning window, they will have worked too many consecutive days.
  ** Do not load all historic entities in memory: even though immovable entities do not affect solving performance, they can cause out of memory problems when the data grows to years. Only load those that might still affect the current constraints with a good safety margin, for example load the past year.
  * _Tentative_ 
  +
  The first few time periods that are being planned freely for the last time. After this planning, their planning entities become <<immovablePlanningEntities,immovable>> or <<nonvolatileReplanning,semi-immovable>>.
  +
  ** The result of the tentative planning is usually shared with the business. For example, in nurse rostering, the nurses will use this schedule to plan their personal lives. Changing that schedule later becomes disruptive, however, were exceptions force us to do so, disruption can be minimized (see <<nonvolatileReplanning,Nonvolatile Replanning>>).
  * _Draft_ 
  +
  The latter time periods that are being planned freely, but not for the last time. They are likely to change again in the next planning effort.
  +
  ** The draft part is needed to assure that the tentatively planned entities will allow room of a good, feasible planning afterwards. 
  +
  ** That draft part is usually not shared with the business yet, because it is too volatile. However, it is stored in the database and used a starting point for the next plan.
  
  * _Future_ (out of scope)
  + 
  Planning entities that are not in the current planning window.
  +
  ** If <<assigningTimeToPlanningEntities,time is a planning variable>>, there is no future part. Instead, if the planning window is too small to plan all entities, see  <<overconstrainedPlanning,overconstrained planning>>.
  
  image::RepeatedPlanning/continuousPlanningEmployeeRostering.png[align="center"]
  
  In the employee rostering example above, we re-plan every four days.
  Each time, we actually plan a window of 12 days, but we only share the tentative roster of the next four days with the employees.
  
  [NOTE]
  