Docs
  • Solver
  • Models
    • Field Service Routing
    • Employee Shift Scheduling
    • Pick-up and Delivery Routing
  • Platform
Try models
  • Timefold Solver SNAPSHOT
  • Using Timefold Solver
  • Building a service (Preview)
  • Constraint weights (optional)
  • Edit this Page

Timefold Solver SNAPSHOT

    • Introduction
    • PlanningAI concepts
    • Getting started
      • Overview
      • Hello World Quick Start Guide
      • Quarkus Quick Start Guide
      • Spring Boot Quick Start Guide
      • Vehicle Routing Quick Start Guide
    • Using Timefold Solver
      • Using Timefold Solver: Overview
      • Configuring Timefold Solver
      • Modeling planning problems
      • Running Timefold Solver
      • Benchmarking and tweaking
      • Building a service (Preview)
        • REST API
        • Service Model and Enricher
        • Constraint weights (optional)
        • Demo data (optional)
        • Exposing metrics (optional)
    • Constraints and score
      • Constraints and Score: Overview
      • Score calculation
      • Understanding the score
      • Adjusting constraints at runtime
      • Load balancing and fairness
      • Performance tips and tricks
    • Optimization algorithms
      • Optimization Algorithms: Overview
      • Construction heuristics
      • Local search
      • Exhaustive search
      • Neighborhoods: A new way to define custom moves
      • Move Selector reference
    • Responding to change
    • Integration
    • Design patterns
    • 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

Constraint weights (optional)

When implementing a model, it’s important to set up the weights of the constraints correctly. Having good default weights makes the model easily reusable and is an expression of your modeling expertise.

This page describes features which are only relevant when running Timefold Solver as a Service (Preview). The information on these pages may describe functionality which may be changed or even removed in a future release.

Constraint weights are always an interpretation by the modeler. It might be that the consumer of the model would like to see the constraints weighed differently. ModelConfigOverrides allows consumers of a model to tailor constraint weights and parameters to their use case.

Be careful not to make your model overly configurable as that impacts usability.

1. Adjusting constraint weights

Implement the ModelConfigOverrides interface. This is a marker interface, meaning it has no methods but can be discovered by the SDK. The implementation should have fields that refer to specific constraints using the @ConstraintReference annotation. To ensure both the constraint and this reference are the same, use a static field to keep the name of the constraint.

The example ConstraintProvider class.
public class TimetableConstraintProvider implements ConstraintProvider {

    public static final String TEACHER_CONFLICT = "Teacher conflict";
    public static final String ROOM_CONFLICT = "Room conflict";

    Constraint roomConflict(ConstraintFactory constraintFactory) {
        return constraintFactory
                // constraint implementation excluded
                .asConstraint(ROOM_CONFLICT);
    }

    Constraint teacherConflict(ConstraintFactory constraintFactory) {
        return constraintFactory
                // constraint implementation excluded
                .asConstraint(TEACHER_CONFLICT);
    }

    // other constraints excluded
}
The ModelConfigOverrides class.
public final class TimetableConfigOverrides implements ModelConfigOverrides {

    public static final long DEFAULT_WEIGHT_ZERO = 0L;
    public static final long DEFAULT_WEIGHT_ONE = 1L;

    @ConstraintReference(TimetableConstraintProvider.TEACHER_CONFLICT)
    private long teacherConflictWeight = DEFAULT_WEIGHT_ONE;

    @ConstraintReference(TimetableConstraintProvider.ROOM_CONFLICT)
    private long roomConflictWeight = DEFAULT_WEIGHT_ONE;

    // getter/setter excluded

}

The default constraint weight for these constraints is 1. This can now be overridden by the consumer by passing in the model overrides object in a request. For example, to make the Teacher conflict 10 times more impactful, override the weight to 10:

Example Request to change the weight.
{
    "config": {
      "run": {
        "name": "run name",
        <some fields excluded>
      },
      "model": {
        "overrides": {
          "teacherConflictWeight": 10
        }
      }
    },
    "modelInput" : <ModelInput class as JSON>
}
Only allow weight overrides if it makes sense. Usually, it doesn’t make sense to allow weight overrides for hard constraints.

Next, in the model converter, make sure to map these overrides to a solver specific ConstraintWeightOverrides object that must be on the @PlanningSolution class.

As part of the ModelConverter
TimetableConfigOverrides modelConfigOverrides = modelConfig.overrides();

ConstraintWeightOverrides<HardMediumSoftLongScore> constraintWeightOverrides = ConstraintWeightOverrides.none();
constraintWeightOverrides = ConstraintWeightOverrides.of(
                    Map.ofEntries(
                        Map.entry(TEACHER_CONFLICT,
                                HardMediumSoftLongScore.ofHard(modelConfigOverrides.getTeacherConflictWeight())),
                        Map.entry(ROOM_COMFLICT,
                                HardMediumSoftLongScore
                                        .ofSoft(modelConfigOverrides.getRoomConflictWeight()));

solverModel.setConstraintWeightOverrides(constraintWeightOverrides);

For more information, see Adjusting constraints at runtime.

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