Solver doesnt try to optimize solution ( one hard constraint, one soft constraint )

Viewed 31

I got 2 constraints :

one HARD ( 100 score ) one SOFT ( 100 score )

When i run the solver, it's like he just try to resolve the hard one, and doesn't look for the soft one. I have no softScore, optaplanner return a 0Hard/0Medium/0Soft.

My HARD constraint is : a worker can't work more than 5 days in a row

My SOFT constraint is : try to put the most of working days possible ( calculated by hours of work )

My test is for two weeks. A worker need to be above 66 hours of work, is he is under we penalize more.

Here the two constraints in JAVA:

the SOFT one :

  private Constraint averageWorkingHours(ConstraintFactory constraintFactory) {
        return constraintFactory
                .from(WorkingDay.class)
                .filter((wd) -> wd.isFreeToWork())
                .groupBy(WorkingDay::getAgent,
                        WorkingDay::hasBreakDayBySolver,
                // hasBreakDayBySolver return if the solver has put my 
                @PlanningVariable ( a breakDay ) in the WorkingDay
                        ConstraintCollectors.count())
                .filter((agent, hasBreakDayBySolver, count) -> {
                    return !hasBreakDayBySolver;
                })
                .penalizeConfigurable(AVERAGE_HOURS_WORKING, ((agent, hasBreakDayBySolver, count) -> {
                    // a worker need to be above 66 hours of work for 2 weeks
                    
                    // We penalize more if a worker is under the average of working hours wanted for two weeks ( 66 )
                    if(count * 7 < 66){  // count * hours worked for one day
                        return (66 - count * 7) * 2 ;
                    }
                    else{
                        return count * 7 - 66;
                    }
                }));
    }

the HARD one :

private Constraint fiveConsecutiveWorkingDaysMax(ConstraintFactory constraintFactory) {
    return constraintFactory
            .from(WorkingDay.class)
            .filter(WorkingDay::hasWork)
            .join(constraintFactory.from(WorkingDay.class)
                            .filter(WorkingDay::hasWork),
                    Joiners.equal(WorkingDay::getAgent),
                    Joiners.greaterThan(wd->wd.getDayJava()),
                    Joiners.filtering((wd1, wd2)->{
                        LocalDate fourDaysBefore = wd1.getDayJava().minusDays(4);
                        Boolean wd2isAfterFourDaysBeforeWd1 = wd2.getDayJava().compareTo(fourDaysBefore) >= 0;
                        return wd2isAfterFourDaysBeforeWd1;
                    })
            )
            .groupBy((wd1, wd2) -> wd2, ConstraintCollectors.countBi())
            .filter((wd2, count) -> count >= 4) 
            .penalizeConfigurable(FIVE_CONSECUTIVE_WORKING_DAYS_MAX,((wd2, count)-> count - 3));
}

I hope my explanations are clear.

Thanx !

1 Answers
Related