<commit_before>[[designPatterns]]
= Design Patterns
:doctype: book
:imagesdir: ..
:sectnums:
:toc: left
:icons: font
:experimental:


[[designPatternsIntroduction]]
== Design patterns introduction

The design patterns in this section list and solve common design challenges.
//Need to explain what design patterns are.

[[domainModelingGuide]]
== Domain modeling guidelines

Follow the guidelines listed in this section to create a well thought-out model that can contribute significantly to the success of your planning.


. *Draw a class diagram of your domain model.*
.. Normalize the diagram to remove duplicate data.
// what does it mean to normalize a diagram?
.. Create sample instances for each class. For example, in the Employee Rostering starter application, the samples for the `Employee` class are `Ann`, `Bert`, and `Carl`.

. *Determine which relationships (or fields) change during planning and color them orange.* One side of these relationships will become a planning variable later on. For example, in the Employee Rostering starter application, the `Shift` to `Employee` relationship changes during planning, so it is orange. However, other relationships, such as from `Employee` to `Skill`, are immutable during planning
because Optaplanner cannot assign an extra skill to an employee.

. *If there are multiple relationships (or fields), check for <<shadowVariable,shadow variables>>*.
A shadow variable changes during planning, but its value can be calculated based on one or more genuine planning variables, without dispute. Color shadow relationships (or fields) purple.
+
[NOTE]
====
Only one side of a bidirectional relationship can be a genuine planning variable.The other side will become an <<bidirectionalVariable,inverse relation shadow variable>> later on. Keep bidirectional relationships orange.
====

. *Check for <<chainedPlanningVariable,chained planning variables>>*.
In a chained variable design, the focus is on deciding the order of a set of planning entity instances instead of assigning them to a date and time. However,  a shadow variable can assign the date and time.
A typical use case is <<vehicleRouting,vehicle routing>>.

. *If there is an orange many-to-many relationship, replace it
with a one-to-many and a many-to-one relationship to a new intermediate class.*
+
[NOTE]
====
Optaplanner does not currently support a `@PlanningVariable` annotation on a collection.
====
//I suggest removing this for now, the when you do implement `@PlanningVariable` add this note saying why you shouldn't use it: Although a future version will support it for flexibility reasons. it probably has an inherit performance and complexity cost, so it might be better to avoid it anyway.
+
For example, in the Employee Rostering starter applicaion the `ShiftAssignment` class is the many-to-many relationship between `Shift` and `Employee`.
`Shift` contains every shift time that needs to be filled with an employee.
+
image::DesignPatterns/employeeShiftRosteringModelingGuideA.png[align="center"]

. *Annotate a many-to-one relationship with a `@PlanningEntity` annotation.* Usually the _many_ side of the relationship is the planning entity class that contains the planning variable. If the relationship is bidirectional, both sides are a planning entity class but usually the _many_ side has the planning variable and the _one_ side has the shadow variable. For example, in the Employee Rostering starter application, the `ShiftAssignment` class has an `@PlanningEntity` annotation.

. *Make sure that the planning entity class has at least one problem property*. A planning entity class cannot consist of only planning variables or an ID and only planning variables.
.. Remove any surplus `@PlanningVariable` annotations so that they become  problem properties. Doing this significantly decreases <<searchSpaceSize,the search space size>> and significantly increases solving efficiency. For example, in the Employee Rostering starter application, the `ShiftAssignment` class should not annotate both the `Shift` and `Employee` relationship with `@PlanningVariable`.
.. Make sure that when all planning variables have a value of `null`, the planning entity instance is describable to the business people. Planning variables have a value of `null` when the planning solution is uninitialized.
** A surrogate ID does not suffice as the required minimum of one problem property.
** There is no need to add a hard constraint to assure that two planning entities are different. They are already different due to their problem properties.
** In some cases, multiple planning entity instances have the same set of problem properties. In such cases, it can be useful to create an extra problem property to distinguish them. For example, in the Employee Rostering starter application, the `ShiftAssignment` class has the problem property `Shift` as well as the problem property `indexInShift` which is an `int` class.

. *Choose the model in which the number of planning entities is fixed during planning*. For example, in the Employee Rostering starter application, it is impossible to know in advance how many shifts each employee will have before Optaplanner solves the model and the results can differ for each solution found.
On the other hand, the number of employees per shift is known in advance,
so it is better to make the `Shift` relationship a problem property
and the `Employee` relationship a planning variable.
+
image::DesignPatterns/employeeShiftRosteringModelingGuideB.png[align="center"]

// Not clear just what this diagram is showing:

image::DesignPatterns/entityVariableAndValueExamples.png[align="center"]

[NOTE]
====
Vehicle routing is an exception because it uses a <<chainedPlanningVariable,chained planning variable>>.
====


[[assigningTimeToPlanningEntities]]
== Assigning Time to Planning Entities

Dealing with time and dates in planning problems may be problematic because it is dependent on the needs of your use case.

There are several representations of timestamps, dates, durations and periods in Java.
Choose the right representation type for your use case:

* `java.util.Date` (deprecated): a slow, error-prone way to represent timestamps. Do not use.
* ``java.time.LocalDateTime``, ``LocalDate``, ``DayOfWeek``, ``Duration``, ``Period``, ...: an accurate way to represent and calculate with timestamps, dates, ...
** Supports timezones and DST (Daylight Saving Time).
** Requires Java 8 or higher.
* `int` or ``long``: Caches a timestamp as a simplified number of coarse-grained time units (such as minutes) from the start of the global planning time window or the epoch.
** For example: a `LocalDateTime` of `1-JAN 08:00:00` becomes an `int` of `400` minutes. Similarly `1-JAN 09:00:00` becomes `460` minutes.
** It often represents an extra field in a class, alongside the `LocalDateTime` field from which it was calculated. The `LocalDateTime` is used for user visualization, but the `int` is used in the score constraints.
** It is faster in calculations, which is especially useful in the TimeGrain pattern.<commit_msg>BXMSDCO-4615 updated with SME comments<commit_after>[[designPatterns]]
= Design Patterns
:doctype: book
:imagesdir: ..
:sectnums:
:toc: left
:icons: font
:experimental:


[[designPatternsIntroduction]]
== Design patterns introduction

OptaPlanner design patterns are generic reusable solutions to common challenges in the model or architecture of projects that perform constraint solving. The design patterns in this section list and solve common design challenges.

[[domainModelingGuide]]
== Domain modeling guidelines

Follow the guidelines listed in this section to create a well thought-out model that can contribute significantly to the success of your planning.


. *Draw a class diagram of your domain model.*
.. Make sure there are no duplications in your data model and that relationships between objects are clearly defined.

.. Create sample instances for each class. For example, in the Employee Rostering starter application, the samples for the `Employee` class are `Ann`, `Bert`, and `Carl`.

. *Determine which relationships (or fields) change during planning and color them orange.* One side of these relationships will become a planning variable later on. For example, in the Employee Rostering starter application, the `Shift` to `Employee` relationship changes during planning, so it is orange. However, other relationships, such as from `Employee` to `Skill`, are immutable during planning
because Optaplanner cannot assign an extra skill to an employee.

. *If there are multiple relationships (or fields), check for <<shadowVariable,shadow variables>>*.
A shadow variable changes during planning, but its value can be calculated based on one or more genuine planning variables, without dispute. Color shadow relationships (or fields) purple.
+
[NOTE]
====
Only one side of a bidirectional relationship can be a genuine planning variable.The other side will become an <<bidirectionalVariable,inverse relation shadow variable>> later on. Keep bidirectional relationships orange.
====

. *Check for <<chainedPlanningVariable,chained planning variables>>*.
In a chained variable design, the focus is on deciding the order of a set of planning entity instances instead of assigning them to a date and time. However,  a shadow variable can assign the date and time.
A typical use case is <<vehicleRouting,vehicle routing>>.

. *If there is an orange many-to-many relationship, replace it
with a one-to-many and a many-to-one relationship to a new intermediate class.*
+
[NOTE]
====
Optaplanner does not currently support a `@PlanningVariable` annotation on a collection.
====

+
For example, in the Employee Rostering starter applicaion the `ShiftAssignment` class is the many-to-many relationship between `Shift` and `Employee`.
`Shift` contains every shift time that needs to be filled with an employee.
+
image::DesignPatterns/employeeShiftRosteringModelingGuideA.png[align="center"]

. *Annotate a many-to-one relationship with a `@PlanningEntity` annotation.* Usually the _many_ side of the relationship is the planning entity class that contains the planning variable. If the relationship is bidirectional, both sides are a planning entity class but usually the _many_ side has the planning variable and the _one_ side has the shadow variable. For example, in the Employee Rostering starter application, the `ShiftAssignment` class has an `@PlanningEntity` annotation.

. *Make sure that the planning entity class has at least one problem property*. A planning entity class cannot consist of only planning variables or an ID and only planning variables.
.. Remove any surplus `@PlanningVariable` annotations so that they become  problem properties. Doing this significantly decreases <<searchSpaceSize,the search space size>> and significantly increases solving efficiency. For example, in the Employee Rostering starter application, the `ShiftAssignment` class should not annotate both the `Shift` and `Employee` relationship with `@PlanningVariable`.
.. Make sure that when all planning variables have a value of `null`, the planning entity instance is describable to the business people. Planning variables have a value of `null` when the planning solution is uninitialized.
** A surrogate ID does not suffice as the required minimum of one problem property.
** There is no need to add a hard constraint to assure that two planning entities are different. They are already different due to their problem properties.
** In some cases, multiple planning entity instances have the same set of problem properties. In such cases, it can be useful to create an extra problem property to distinguish them. For example, in the Employee Rostering starter application, the `ShiftAssignment` class has the problem property `Shift` as well as the problem property `indexInShift` which is an `int` class.

. *Choose the model in which the number of planning entities is fixed during planning*. For example, in the Employee Rostering starter application, it is impossible to know in advance how many shifts each employee will have before Optaplanner solves the model and the results can differ for each solution found.
On the other hand, the number of employees per shift is known in advance,
so it is better to make the `Shift` relationship a problem property
and the `Employee` relationship a planning variable as shown in the following examples.
+
image::DesignPatterns/employeeShiftRosteringModelingGuideB.png[align="center"]

In the following diagram, each row is a different example and shows the relationship in that example's data model. For the *N Queens* example, the Queen entity has a Row planning variable, which stores objects of type `row`. Many Queens may point to one Row.

image::DesignPatterns/entityVariableAndValueExamples.png[align="center"]

[NOTE]
====
Vehicle routing is different because it uses a <<chainedPlanningVariable,chained planning variable>>.
====

[[assigningTimeToPlanningEntities]]
== Assigning Time to Planning Entities

Dealing with time and dates in planning problems may be problematic because it is dependent on the needs of your use case.

There are several representations of timestamps, dates, durations and periods in Java.
Choose the right representation type for your use case:

* `java.util.Date` (deprecated): a slow, error-prone way to represent timestamps. Do not use.
* ``java.time.LocalDateTime``, ``LocalDate``, ``DayOfWeek``, ``Duration``, ``Period``, ...: an accurate way to represent and calculate with timestamps, dates, ...
** Supports timezones and DST (Daylight Saving Time).
** Requires Java 8 or higher.
* `int` or ``long``: Caches a timestamp as a simplified number of coarse-grained time units (such as minutes) from the start of the global planning time window or the epoch.
** For example: a `LocalDateTime` of `1-JAN 08:00:00` becomes an `int` of `400` minutes. Similarly `1-JAN 09:00:00` becomes `460` minutes.
** It often represents an extra field in a class, alongside the `LocalDateTime` field from which it was calculated. The `LocalDateTime` is used for user visualization, but the `int` is used in the score constraints.
** It is faster in calculations, which is especially useful in the TimeGrain pattern.
{'fraction_non_alphanumeric': 0.06375087473757873, 'fraction_numerical': 0.003219034289713086, 'mean_word_length': 5.138745704467354, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3405735', 'n_tokens_mistral': 3455, 'n_tokens_neox': 3305, 'n_words': 1971}