Domain modeling guide
This guide provides reusable solutions to common challenges when modeling a planning problem. Follow these guidelines to create a well thought-out model that can contribute significantly to the success of your planning.
1. Domain modeling guidelines
-
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
Employeeclass, createAnn,Bert, andCarl.
-
-
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 employee rostering, the
ShifttoEmployeerelationship changes during planning, so it is orange. However, other relationships, such as fromEmployeetoSkill, are immutable during planning because Timefold Solver cannot assign an extra skill to an employee. -
If there are multiple relationships (or fields), check for 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.
Only one side of a bi-directional relationship can be a genuine planning variable. The other side will become an inverse relation shadow variable later on. Keep bi-directional relationships orange.
-
If the goal is to find an optimal order of elements, use the Chained Through Time pattern.
-
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.
The following figure illustrates introducing a
ShiftAssignmentclass to represent the many-to-many relationship betweenShiftandEmployee.Shiftcontains every shift time that needs to be filled with an employee.
Timefold Solver does not currently support a
@PlanningVariableannotation on a collection. Planning list variable is not a means of achieving a many-to-one relationship; it serves to indicate that these values happen in a sequence one after another. -
Annotate a many-to-one relationship with a
@PlanningEntityannotation. Usually the many side of the relationship is the planning entity class that contains the planning variable. If the relationship is bi-directional, 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 employee rostering, theShiftAssignmentclass has an@PlanningEntityannotation. -
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
@PlanningVariableannotations so that they become problem properties. Doing this significantly decreases the search space size and significantly increases solving efficiency. For example, in employee rostering, theShiftAssignmentclass should not annotate both theShiftandEmployeerelationship 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 ofnullwhen 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 employee rostering, the
ShiftAssignmentclass has the problem propertyShiftas well as the problem propertyindexInShiftwhich is anintclass.
-
-
-
Choose the model in which the number of planning entities is fixed during planning. For example, in the employee rostering, it is impossible to know in advance how many shifts each employee will have before Timefold Solver 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
Shiftrelationship a problem property and theEmployeerelationship a planning variable as shown in the following examples.