Search code examples
javaoptimizationconstraintsoptaplanner

Optaplanner: constraint on tuples ? (three elements)


I'm trying to use optaplanner to generate a schedule for a university. I would like to limit the number of courses given by a teacher, every day, to 2.

By using constraints, I know how to enforce a limit at one, e.g:

        return constraintFactory
                .forEachUniquePair(Lesson.class,
                        Joiners.equal(Lesson::getTeacher)
                        Joiners.equal((lesson) -> lesson.getStart().toLocalDate()))
                .penalize("Limit to one course per date", HardSoftScore.ONE_SOFT);

It's easy because I only have to deals with pairs, and there is a forEachUniquePair. Is there such a thing as a forEachUniqueTriplet for optaplanner ?


Solution

  • No, there is not. However, forEachUniquePair is syntactic sugar for

    forEach(Lesson.class)
        .join(Lesson.class, Joiners.lessThan(Lesson::getId))
    

    By applying the same pattern on the third Lesson, you will get the result you need. That said, the logic of the joiner may need to be a bit different to actually give unique triplets. In fact, it may be easier (but not the most performant) to just do

    forEach(Lesson.class)
        .join(Lesson.class, Joiners.lessThan(Lesson::getId))
        .join(Lesson.class)
        .filter((lesson1, lesson2, lesson3) -> lesson3 != lesson2 && lesson3 != lesson1)