繁体   English   中英

过度约束的计划未按预期工作

[英]Overconstrained planning not working as expected

我一直试图让过度约束的计划适合我的情况,但仍然遇到一些失败的硬约束仍然被分配的问题。 抱歉,如果之前已经回答过这个问题,但是我看到的大多数示例/解决方案都以 Drools 为中心,我在这个项目中使用流 API。 如果有帮助,请使用 optaplanner 的 quarkus 1.4.2 实现。

以下是我要完成的一些示例限制:

private Constraint unnassignedPerson(ConstraintFactory constraintFactory) {
    return constraintFactory.from(Assignment.class)
            .filter(assignment -> assignment.getPerson() == null)
            .penalize("Unassigned", HardMediumSoftScore.ONE_MEDIUM);

private Constraint numberAssignmentConflict(ConstraintFactory constraintFactory) {
    return constraintFactory.from(Assignment.class)
            .join(Assignment.class,
                    Joiners.equal(Assignment::getPerson),
                    Joiners.equal(Assignment::getNumber),
                    Joiners.lessThan(Assignment::getId))
            .penalize("Number Conflict", HardMediumSoftScore.of(2, 0, 0));

private Constraint tooLittleSpaceBetweenResourceAssignment(ConstraintFactory constraintFactory) {
    return constraintFactory.from(Assignment.class)
            .join(Assignment.class, Joiners.equal(Assignment::getPerson), Joiners.lessThan(Assignment::getId))
            .filter((assignment, assignment2) -> !assignment.getResourceId().equals(assignment2.getResourceId()))
            .filter(((assignment, assignment2) -> inRange(1, assignment.getNumber(), assignment2.getNumber())))
            .penalize("Not enough space between assignments of different resource (requires 1)", HardMediumSoftScore.of(1, 0, 0));
}

(inRange 是一个简单的局部 function 来获取两个数字之间的绝对差)

请注意,在尊重可为空的计划变量方面,它们彼此独立工作 - 只有当两者都启用时,我才会得到意想不到的结果。 当两者都启用时,尽管在调试日志中显示为硬约束(在我的本地测试中总是以 -12hard/-2medium/0soft 结束),但仍会在解决方案中分配具有较低硬分的那个。

任何关于我可能做错了什么的见解将不胜感激,并在此先感谢:)

作为后续,看来我的分配冲突约束的Joiners.lessThan(Assignment::getId)部分与可为空的分配兼容。 我删除了它并添加了一些更明确的检查,现在一切正常:D

对任何可能有帮助的人的伪适应:

private Constraint numberAssignmentConflict(ConstraintFactory constraintFactory) {
    return constraintFactory.from(Assignment.class)
            .join(Assignment.class,
                    Joiners.equal(Assignment::getPerson),
                    Joiners.equal(Assignment::getNumber))
            .filter(((assignment, assignment2) -> assignment.getPerson() != null && assignment2.getPerson() != null))
            .filter(((assignment, assignment2) -> !assignment.getId().equals(assignment2.getId())))
            .penalize("Number Conflict", HardMediumSoftScore.of(2, 0, 0));
}

第一个约束不是必须是fromUnfiltered(Assignment.class)而不是from(Assignment.class) 我相信from()不会传递具有未分配计划变量的实体,因此永远不会应用 ONE_MEDIUM 惩罚?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM