Search code examples
optaplannertimefold

Load balancing of resources in timefold SelectionSorterWeightFactory vs Constraints


I have an objective to evenly distribute tasks among employees using Timefold Solver.

I have come across two approaches that seem to address this goal:

  1. SelectionSorterWeightFactory

    int leftEmployeeWorkedHours = scoreDirector.computeConstraintWeight(
         "Employee worked hours",
         ConstraintCollectors.sum(shiftAssignment -> shiftAssignment.getEmployee().equals(leftShiftAssignment.getEmployee()) ? shiftAssignment.getDuration() : 0)
     );
     int rightEmployeeWorkedHours = scoreDirector.computeConstraintWeight(
         "Employee worked hours",
         ConstraintCollectors.sum(shiftAssignment -> shiftAssignment.getEmployee().equals(rightShiftAssignment.getEmployee()) ? shiftAssignment.getDuration() : 0)
     );
    
     // Compare the total worked hours to achieve load balancing
     return Integer.compare(leftEmployeeWorkedHours, rightEmployeeWorkedHours);
    
  2. Another option is to use Constraint like this

[referred from https://docs.timefold.ai/timefold-solver/latest/constraints-and-score/load-balancing-and-fairness ]

   Constraint fairAssignments(ConstraintFactory constraintFactory) {
    return constraintFactory.forEach(ShiftAssignment.class)
            .groupBy(ConstraintCollectors.loadBalance(ShiftAssignment::getEmployee))
            .penalizeBigDecimal(HardSoftBigDecimalScore.ONE_SOFT, LoadBalance::unfairness)
            .asConstraint("fairAssignments");}

My understanding is that if the goal is to influence the selection process, such as balancing workloads or prioritizing preferred options, then the SelectionSorterWeightFactory approach may be more suitable. On the other hand, the Constraint Factory approach is better suited for driving resource limitations and business rules.

However, I would like to get more clarity on the following:

  1. When should I choose one approach over the other, or should I use a combination of both?

  2. What are the key differences between the two approaches, and how do they influence the solver's decision-making process?

  3. Can you provide any additional insights or guidelines on how to choose the appropriate approach for my use case?

Your clarification on these aspects would be greatly appreciated. Thank you for your time and assistance.


Solution

  • If load balancing is a requirement of the problem, it needs to be in the constrains, and it needs appropriately weighted. That is the only way to ensure the solver will actually take it into account - remember that in the end, the only thing that matters to the solver is finding the best score; if the constraints do not include load balancing, the solution will not be balanced.

    Personally, I would stay well away from obscure tweaking of selectors. There are a myriad options there with all sorts of interactions between each other. I find that going down this rabbit hole is a great time sink, often for no real benefit.

    YMMV but if you decide to do this, absolutely make sure you benchmark every tweak you make. Only make sure you use the tweaks which are proven to provide improved solutions across a wide variety of data sets. A sample size of one is far from enough.