When attempting to upgrade to Optaplanner 9 I encountered some changes in solutions. Running with full assert revealed some score corruption issues that had not previously been present. Tracing back it appears that the issue first appeared with Version 8.34.0.
The problem appears to be specific to Bavet
as it does not reproduce when I switch to a DROOLS CS implementation.
It seems that the issue is possibly related to Joiners
because by changing my implementation from something like
private static Constraint pegConstraint(final ConstraintFactory factory) {
return factory.forEach(Thing.class).map(This::getName)
.join(factory.forEach(Hole.class).map(Hole::getPeg),
Joiners.filtering((name, hole) -> !hole.getPeg().isSquare())
.join(factory.forEach(Hole.class).map(Hole::getPeg))
.map((name, peg1, peg2) -> someAccumulator())
.penalizeLong(HardSoftLongScore.ofSoft(1L), p -> p).asConstraint("constraint");
to using a filter like
private static Constraint pegConstraint(final ConstraintFactory factory) {
return factory.forEach(Thing.class).map(This::getName)
.join(factory.forEach(Hole.class).map(Hole::getPeg)))
.filter((name, hole) -> !hole.getPeg().isSquare())
.join(factory.forEach(Hole.class).map(Hole::getPeg))
.map((name, peg1, peg2) -> someAccumulator())
.penalizeLong(HardSoftLongScore.ofSoft(1L), p -> p).asConstraint("constraint");
the score corruption warnings go away, but the streams are significantly slower. Am I misusing Joiners.filtering()
or is something else at play?