如何启用可为空的 InverseRelationShadowVariable 或防止为 PlanningListVariable 赋值

问题描述 投票:0回答:1

我必须计划一份机器订单清单。

关联订购机是按商品代码。如果机器有订单项目代码,机器可以管理订单,以便可以将订单分配给机器。

某些订单的商品代码可能与任何机器都不匹配。

这是我的代码:

@PlanningEntity
public class Machine {

    private List<Order> m_plannedOrders;
...
    @PlanningListVariable
    public List<Order> getPlannedOrders() {
        return m_plannedOrders;
    }

    public void setPlannedOrders(List<Order> orders) {
        m_plannedOrders = orders;
    }
...
    public boolean canManage(String itemCode) {
        return true if this machine can handle the order by code.
    }
}

@PlanningEntity
public class Order {
    private Machine m_machine;
...
    @InverseRelationShadowVariable(sourceVariableName = "plannedOrders")
    public Machine getMachine() {
        return m_machine;
    }

    public void setMachine(Machine machine) {
        m_machine = machine;
    }

    public boolean isValidMachine() {
        boolean retVal = false;

        if (m_machine != null) {
            retVal = m_machine.canManage(m_itemCode);
        }

        return retVal;
    }
}

@PlanningSolution
public class MachineOrdersPlanning {
...
    @PlanningEntityCollectionProperty
    public List<Machine> getMachines() {
        return m_machines;
    }

    @ValueRangeProvider
    @ProblemFactCollectionProperty
    public List<Order> getOrders() {
        return m_orders;
    }

    @PlanningScore
    public HardSoftScore getScore() {
        return m_score;
    }
}

我使用的约束是:

    private Constraint orderOnCorrectMachine(ConstraintFactory constraintFactory) {
        return constraintFactory
                .forEach(Order.class)
                .filter(order -> order.getMachine() == null || !order.isValidMachine())
                .penalize(HardSoftScore.ONE_HARD).asConstraint("Order assigned to valid machine");
    }

我也尝试过没有

order.getMachine() == null || 

问题是机器 1 的输出是

  Machine: 1
    Order 29 canManaged? true
    Order 18 canManaged? true
    Order 16 canManaged? true
    Order 15 canManaged? true
    Order 14 canManaged? true
    Order 9 canManaged? true
    Order 8 canManaged? true
    Order 6 canManaged? false
    Order 4 canManaged? true

订单 6 分配给一台机器,因为计划变量不能为空。 但 InverseRelationshadowVariable 不接受注释中可为空。

我的愿望是所有无法管理的订单都不会被分配。 我是否必须在某处注释中使用可空值,或者我必须更改约束还是其他什么?

如有任何帮助,我们将不胜感激。

optaplanner timefold
1个回答
0
投票

简单(可能不是最佳)的方法是创建一个额外的“虚拟”机器,能够处理任何类型的订单并使用 HardMediumScore 和两个约束:

  • 硬分数约束与您必须对分配的不兼容订单进行惩罚相同
  • 中等分数约束,仅对分配给“虚拟”机器的订单数量进行惩罚

您仍然可以使用软规则的软分数。

© www.soinside.com 2019 - 2024. All rights reserved.