Tom Mutimer
Tom Mutimer

Reputation: 15

Optaplanner - Constraint streams groupBy

I am trying to solve a scheduling problem, which centers around the following arrangement:

Equipment <- Task <- ShiftAssignment(Planning Variable) -> Shift

Tasks have a problem fact of their equipment usage; each may reference a specific Equipment instance or instances, with an associated time in minutes. It takes up that time for that equipment in the Shift it's assigned to.

Should I be able to achieve the constraint with join() and groupBy()? I've tried pursuing the following route:

    private Constraint doNotOverbookEquipment(ConstraintFactory factory) {
        return factory.from(ShiftAssignment.class)
                // join shift assignments with the shifts they are assignments of
                .join(Shift.class, equal(ShiftAssignment::getShiftId, Shift::getId))
                // join with ALL pieces of equipment
                .join(Equipment.class)
                .groupBy([Shift and Equipment, summing the equipment-usage for each ShiftAssignment])
                .filter([equipment usage greater than a constant])
                .penalizeConfigurable("do not overbook Equipment");

I think the filter() should be no problem, but unsure exactly how to get this groupBy() to achieve what I want. Do I need a TriConstraintCollector here? Or is there a different, better overall approach?

For reference, the ShiftAssignment class can easily have a method like the following:

public LinkedHashSet<Equipment, Integer> getEquipmentUsage()

Upvotes: 1

Views: 1395

Answers (1)

I think that your groupBy() would look something like this:

.groupBy(
    (shiftAssignment, shift, equipment) -> shift,
    (shiftAssignment, shift, equipment) -> equipment,
    ConstraintCollectors.sum((shiftAssignment, shift, equipment) ->
        shiftAssignment.getUsage(shift, equipment)
)

The actual logic of what is to be summed should, in this case, be implemented in shiftAssignment.getUsage(...) or any other method you choose to use there.

Upvotes: 2

Related Questions