javatimefold

How to iterate through an array inside the TimeFold constraint stream


We have a day setting class as follows:

public class DaySetting {
        String businessDate;
        Integer weekNo;
        Integer monthNo;
        ArrayList<StandardWorkAmount>standardWorkAmounts;
    }

And have standard work amount class:

public class StandardWorkAmount {
    String jobType;
    Integer  workMinutes;
    
    public String getJobType() {
        return jobType;
    }
    public void setJobType(String jobType) {
        this.jobType = jobType;
    }
    public Integer getWorkMinutes() {
        return this.workMinutes;
    }
    public void setWorkMinutes(Integer workMinutes) {
        this.workMinutes = workMinutes;
    }
}

Now I want to iterate through ArrayList<StandardWorkAmount>standardWorkAmounts and calculate the score.

Constraint daySettingStandardNumberOfHours(ConstraintFactory constraintFactory) {
        return constraintFactory.forEach(DaySetting.class)
               .filter((daySetting)->daySetting.getStandardWorkAmounts()!= null)
               // Iterate through daySetting.getStandardWorkAmounts and find the optimal choice.
               .penalize(HardMediumSoftScore.ONE_SOFT,

               .asConstraint("Day Settings Standard Number Hours");
    }

How to achieve this?


Solution

  • Iteration through collections is not incremental and as such kills performance of the solver. (The slower the solver, the worse the solutions it will find within a given amount of time.)

    Instead, add DaySetting field to your StandardWorkAmount, make sure your StandardWorkAmount is registered as a problem fact, and then your constraint can be fully incremental like so:

    Constraint daySettingStandardNumberOfHours(ConstraintFactory constraintFactory) {
        return constraintFactory.forEach(DaySetting.class)
               .join(StandardWorkAmount.class,
                   Joiners.equal(Function.identity(), StandardWorkAmount::getDaySetting))
        ...
    }