Docs
  • Solver
  • Models
    • Field Service Routing
    • Employee Shift Scheduling
    • Pick-up and Delivery Routing
  • Platform
Try models
  • Timefold Solver SNAPSHOT
  • Domain modeling
  • Domain modeling guide
  • Edit this Page

Timefold Solver SNAPSHOT

    • Introduction
    • PlanningAI concepts
    • Getting started
      • Build as a service
      • Embed as a library
        • Hello World guide
        • Quarkus guide
        • Spring Boot guide
    • Domain modeling
      • Modeling planning problems
      • Domain modeling guide
      • Time patterns
    • Constraints and score
      • Score calculation
      • Understanding the score
      • Adjusting constraints at runtime
      • Load balancing and fairness
      • Performance tips and tricks
    • Running the Solver
      • As a service
        • REST API
        • Model Enrichment
        • Constraint weights
        • Demo data
        • Exposing metrics
      • As a library
        • Configuring Timefold Solver
        • Constraint weights
        • Quarkus integration
        • Spring Boot integration
        • Persistent storage
    • Diagnosing the Solver
      • Benchmarking
      • Solver diagnostics
    • Optimization algorithms
      • Construction heuristics
      • Local search
      • Exhaustive search
      • Custom moves
        • Neighborhoods API
        • Move Selector reference
    • Deployment
      • Cloud architecture patterns
      • Infrastructure requirements
    • Responding to change
    • Example use cases
      • Vehicle routing (guide)
      • More examples on GitHub
    • FAQ
    • New and noteworthy
    • Upgrading Timefold Solver
      • Upgrading Timefold Solver: Overview
      • Upgrade from Timefold Solver 1.x to 2.x
      • Upgrading from OptaPlanner
      • Backwards compatibility
      • Migration guides
        • Variable Listeners to Custom Shadow Variables
        • Chained planning variable to planning list variable
    • Plus/Enterprise Editions
      • Installation
      • Performance improvements
      • Score analysis
      • Recommendation API
      • Nearby selection
      • Multithreaded solving
      • Partitioned search
      • Constraint profiling
      • Multistage moves
      • Throttling best solution events

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

  1. Draw a class diagram of your domain model.

    1. Make sure there are no duplications in your data model and that relationships between objects are clearly defined.

    2. Create sample instances for each class. For example, in the employee rostering Employee class, create Ann, Bert, and Carl.

  2. 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 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 Timefold Solver cannot assign an extra skill to an employee.

  3. 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.

  4. If the goal is to find an optimal order of elements, use the Chained Through Time pattern.

  5. 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 ShiftAssignment class to represent the many-to-many relationship between Shift and Employee. Shift contains every shift time that needs to be filled with an employee.

    employeeShiftRosteringModelingGuideA

    Timefold Solver does not currently support a @PlanningVariable annotation 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.

  6. 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 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, the ShiftAssignment class has an @PlanningEntity annotation.

  7. 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.

    1. Remove any surplus @PlanningVariable annotations so that they become problem properties. Doing this significantly decreases the search space size and significantly increases solving efficiency. For example, in employee rostering, the ShiftAssignment class should not annotate both the Shift and Employee relationship with @PlanningVariable.

    2. 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 employee rostering, the ShiftAssignment class has the problem property Shift as well as the problem property indexInShift which is an int class.

  8. 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 Shift relationship a problem property and the Employee relationship a planning variable as shown in the following examples.

    employeeShiftRosteringModelingGuideB
  • © 2026 Timefold BV
  • Timefold.ai
  • Documentation
  • Changelog
  • Send feedback
  • Privacy
  • Legal
    • Light mode
    • Dark mode
    • System default