diff --git a/src/main/java/ai/timefold/solver/benchmarks/examples/curriculumcourse/score/CurriculumCourseConstraintProvider.java b/src/main/java/ai/timefold/solver/benchmarks/examples/curriculumcourse/score/CurriculumCourseConstraintProvider.java index f7010a5e..f307569e 100644 --- a/src/main/java/ai/timefold/solver/benchmarks/examples/curriculumcourse/score/CurriculumCourseConstraintProvider.java +++ b/src/main/java/ai/timefold/solver/benchmarks/examples/curriculumcourse/score/CurriculumCourseConstraintProvider.java @@ -75,38 +75,10 @@ Constraint roomOccupancy(ConstraintFactory factory) { // Faster than a simpler f return factory.forEach(Lecture.class) .groupBy(Lecture::getRoom, Lecture::getPeriod, count()) .filter((room, period, count) -> count > 1) - .penalize(ONE_HARD, (room, period, count) -> { - var n = 2; // We're looking for unique pairs. - var nominator = factorial(count); - var denominator = factorial(n) * factorial(count - n); - return nominator / denominator; - }) + .penalize(ONE_HARD, (room, period, count) -> (count * (count - 1)) / 2) .asConstraint("roomOccupancy"); } - private static final int MAX_ANTICIPATED_CONFLICTING_LESSONS = 20; // Arbitrary limit for caching. - private static final int[] FACTORIAL_CACHE = new int[MAX_ANTICIPATED_CONFLICTING_LESSONS]; - - private static int factorial(int number) { - if (number < MAX_ANTICIPATED_CONFLICTING_LESSONS) { - var cache = FACTORIAL_CACHE[number]; - if (cache == 0) { - cache = factorialUncached(number); - FACTORIAL_CACHE[number] = cache; - } - return cache; - } - return factorialUncached(number); - } - - private static int factorialUncached(int number) { - return switch (number) { - case 0, 1 -> 1; - case 2 -> 2; - default -> number * factorial(number - 1); - }; - } - Constraint unavailablePeriodPenalty(ConstraintFactory factory) { return factory.forEach(UnavailablePeriodPenalty.class) .join(Lecture.class, diff --git a/src/main/java/ai/timefold/solver/benchmarks/examples/machinereassignment/score/MachineReassignmentConstraintProvider.java b/src/main/java/ai/timefold/solver/benchmarks/examples/machinereassignment/score/MachineReassignmentConstraintProvider.java index a0a42a15..cfaec568 100644 --- a/src/main/java/ai/timefold/solver/benchmarks/examples/machinereassignment/score/MachineReassignmentConstraintProvider.java +++ b/src/main/java/ai/timefold/solver/benchmarks/examples/machinereassignment/score/MachineReassignmentConstraintProvider.java @@ -1,11 +1,9 @@ package ai.timefold.solver.benchmarks.examples.machinereassignment.score; -import static ai.timefold.solver.core.api.score.stream.ConstraintCollectors.sumLong; +import static ai.timefold.solver.core.api.score.stream.ConstraintCollectors.sum; import static ai.timefold.solver.core.api.score.stream.Joiners.equal; import static ai.timefold.solver.core.api.score.stream.Joiners.filtering; -import java.util.function.BiFunction; - import ai.timefold.solver.benchmarks.examples.machinereassignment.domain.MrBalancePenalty; import ai.timefold.solver.benchmarks.examples.machinereassignment.domain.MrGlobalPenaltyInfo; import ai.timefold.solver.benchmarks.examples.machinereassignment.domain.MrMachine; @@ -53,7 +51,7 @@ protected Constraint maximumCapacity(ConstraintFactory factory) { equal(MrMachineCapacity::getMachine, MrProcessAssignment::getMachine)) .groupBy((machineCapacity, processAssignment) -> machineCapacity.getMachine(), (machineCapacity, processAssignment) -> machineCapacity, - sumLong((machineCapacity, processAssignment) -> processAssignment + sum((machineCapacity, processAssignment) -> processAssignment .getUsage(machineCapacity.getResource()))) .filter(((machine, machineCapacity, usage) -> machineCapacity.getMaximumCapacity() < usage)) .penalize(HardSoftScore.ONE_HARD, @@ -110,7 +108,7 @@ protected Constraint transientUsage(ConstraintFactory factory) { .filter(MrProcessAssignment::isMoved), equal(MrMachineCapacity::getMachine, MrProcessAssignment::getOriginalMachine)) .groupBy((machineCapacity, processAssignment) -> machineCapacity, - sumLong((machineCapacity, processAssignment) -> processAssignment + sum((machineCapacity, processAssignment) -> processAssignment .getUsage(machineCapacity.getResource()))) .filter(((machineCapacity, usage) -> machineCapacity.getMaximumCapacity() < usage)) .penalize(HardSoftScore.ONE_HARD, @@ -130,7 +128,7 @@ protected Constraint loadCost(ConstraintFactory factory) { .join(MrProcessAssignment.class, equal(MrMachineCapacity::getMachine, MrProcessAssignment::getMachine)) .groupBy((machineCapacity, processAssignment) -> machineCapacity, - sumLong((machineCapacity, processAssignment) -> processAssignment + sum((machineCapacity, processAssignment) -> processAssignment .getUsage(machineCapacity.getResource()))) .filter(((machineCapacity, usage) -> machineCapacity.getSafetyCapacity() < usage)) .penalize(HardSoftScore.ONE_SOFT, @@ -148,8 +146,8 @@ protected Constraint balanceCost(ConstraintFactory factory) { .join(MrProcessAssignment.class) .groupBy((penalty, processAssignment) -> penalty, (penalty, processAssignment) -> processAssignment.getMachine(), - sumLong((penalty, processAssignment) -> processAssignment.getUsage(penalty.getOriginResource())), - sumLong((penalty, processAssignment) -> processAssignment.getUsage(penalty.getTargetResource()))) + sum((penalty, processAssignment) -> processAssignment.getUsage(penalty.getOriginResource())), + sum((penalty, processAssignment) -> processAssignment.getUsage(penalty.getTargetResource()))) .penalize(HardSoftScore.ONE_SOFT, this::balanceCost) .asConstraint(MrConstraints.BALANCE_COST); } @@ -186,7 +184,7 @@ protected Constraint serviceMoveCost(ConstraintFactory factory) { return factory.forEach(MrProcessAssignment.class) .filter(MrProcessAssignment::isMoved) .groupBy(MrProcessAssignment::getService, ConstraintCollectors.count()) - .groupBy(ConstraintCollectors.max((BiFunction) (service, count) -> count)) + .groupBy(ConstraintCollectors.max((MrService service, Long count) -> count)) .join(MrGlobalPenaltyInfo.class) .penalize(HardSoftScore.ONE_SOFT, (count, penalty) -> count * penalty.getServiceMoveCostWeight()) diff --git a/src/main/java/ai/timefold/solver/benchmarks/examples/nurserostering/score/NurseRosteringConstraintProvider.java b/src/main/java/ai/timefold/solver/benchmarks/examples/nurserostering/score/NurseRosteringConstraintProvider.java index d38e489b..6a9f9317 100644 --- a/src/main/java/ai/timefold/solver/benchmarks/examples/nurserostering/score/NurseRosteringConstraintProvider.java +++ b/src/main/java/ai/timefold/solver/benchmarks/examples/nurserostering/score/NurseRosteringConstraintProvider.java @@ -100,7 +100,7 @@ Constraint minimumAndMaximumNumberOfAssignments(ConstraintFactory constraintFact ConstraintCollectors.countTri())) .map((employee, contract, shiftCount) -> employee, (employee, contract, shiftCount) -> contract, - (employee, contract, shiftCount) -> contract.getViolationAmount(shiftCount)) + (employee, contract, shiftCount) -> contract.getViolationAmount(shiftCount.intValue())) .filter((employee, contract, violationAmount) -> violationAmount != 0) .penalize(HardSoftBigDecimalScore.ONE_SOFT, (employee, contract, violationAmount) -> violationAmount) .asConstraint("Minimum and maximum number of assignments"); @@ -419,7 +419,7 @@ Constraint unwantedPatternShiftType3DaysPattern(ConstraintFactory constraintFact Constraint loadBalanceShiftAssignments(ConstraintFactory constraintFactory) { return constraintFactory.forEach(ShiftAssignment.class) .groupBy(ShiftAssignment::getEmployee, ConstraintCollectors.count()) - .complement(Employee.class, e -> 0) + .complement(Employee.class, e -> 0L) .groupBy(ConstraintCollectors.loadBalance((e, count) -> e, (e, count) -> count)) .penalizeBigDecimal(HardSoftBigDecimalScore.ONE_SOFT, LoadBalance::unfairness) .asConstraint("loadBalanceShiftAssignments");