【问题标题】:Optaplanner - Constraint streams groupByOptaplanner - 约束流 groupBy
【发布时间】:2020-06-22 13:40:03
【问题描述】:

我正在尝试解决一个调度问题,它围绕以下安排:

Equipment Task ShiftAssignment(计划变量)-> Shift

Tasks的设备使用有问题;每个都可以引用一个特定的Equipment 实例或多个实例,并带有以分钟为单位的相关时间。分配给Shift 中的设备会占用该设备的时间。

我应该能够使用join() 和groupBy() 实现约束吗?我尝试过以下路线:

    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");

我认为filter() 应该没问题,但不确定如何获得这个groupBy() 来实现我想要的。我需要TriConstraintCollector吗?还是有其他更好的整体方法?

作为参考,ShiftAssignment 类可以很容易地拥有如下方法:

public LinkedHashSet<Equipment, Integer> getEquipmentUsage()

【问题讨论】:

    标签: constraints scheduling optaplanner


    【解决方案1】:

    我认为您的 groupBy() 看起来像这样:

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

    在这种情况下,要求和的实际逻辑应该在shiftAssignment.getUsage(...) 或您选择在那里使用的任何其他方法中实现。

    【讨论】:

    • 感谢您的回复。为了澄清,我试图最终使每个“行”都由(Shift,Equipment,[ShiftAssignments 的总和以在 Shift 中使用设备])组成。如果我没记错的话,我认为您提出的 groupBy 会导致 (ShiftAssignment, sum(...))。
    • 好的,又试了一次答案。这将为每对独特的(班次、设备)提供不同的总和。
    • 你如何为 ConstraintCollectors.min() 做同样的事情?
    • 我不明白。你是说min() 不起作用吗?随时问另一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多