Search code examples
timefold

Use a different constraint weight between each resolution


I wanted to know if it was possible for the constraints to have different behavior depending on a parameter provided by the user ?

For example, for the VRP if a user wants to prioritize the distance to travel for a resolution and in the next resolution he wants to prioritize the skills for a type of customer.

Can the weight be changed in the ConstraintProvider with a multiplier for example or is it fixed at initialization time and immutable.

For information I use the Spring module.


Solution

    1. The example you describe sounds like you need @ConstraintConfiguration and @ConstraintWeight. Basically, the dataset has a constraint configuration singleton that enabled/disables constraints (zero weight) and decides their constraint weight. See docs.

    2. Generally, you can do a "join with singleton" for other types of user provided parameters:

      f.forEach(Shift.class) .filter(...) .join(MyParametrization.class) .penalize((shift, myParametrization) -> ...)

      It's not ideal, because it adds a join(), but we don't have a specialized construct for this yet.

    3. If it's type of customer specific, take a look at the matchWeighter. Basically the score impact for a constraint match is constraintWeight multiplied by matchWeight.

      The ConstraintVerifier unit tests only test the matchWeight so the ideal default constraint weights can change easily.