过度约束的计划未按预期工作
Overconstrained planning not working as expected
我一直在努力让过度约束的计划适合我的情况,但让 运行 解决仍在分配一些失败的硬约束的问题。抱歉,如果之前有人回答过这个问题,但我看到的大多数 examples/solutions 都以 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 是一个简单的局部函数,用于获取两个数字之间的绝对差值)
请注意,在遵守可为空的计划变量方面,这两者彼此独立工作 - 只有当两者都启用时,我才会得到意想不到的结果。当两者都启用时,尽管在调试日志中显示为硬约束(在我的本地测试中总是以 -12hard/-2medium/0soft 结束),但硬分值较低的仍然在解决方案中分配。
任何关于我可能做错了什么的见解都将不胜感激,并提前致谢:)
作为后续行动,我的分配冲突约束的 Joiners.lessThan(Assignment::getId)
部分似乎 不 与可为 null 的分配兼容。我删除了它并添加了一些更明确的检查,现在一切正常了: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 惩罚?
我一直在努力让过度约束的计划适合我的情况,但让 运行 解决仍在分配一些失败的硬约束的问题。抱歉,如果之前有人回答过这个问题,但我看到的大多数 examples/solutions 都以 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 是一个简单的局部函数,用于获取两个数字之间的绝对差值)
请注意,在遵守可为空的计划变量方面,这两者彼此独立工作 - 只有当两者都启用时,我才会得到意想不到的结果。当两者都启用时,尽管在调试日志中显示为硬约束(在我的本地测试中总是以 -12hard/-2medium/0soft 结束),但硬分值较低的仍然在解决方案中分配。
任何关于我可能做错了什么的见解都将不胜感激,并提前致谢:)
作为后续行动,我的分配冲突约束的 Joiners.lessThan(Assignment::getId)
部分似乎 不 与可为 null 的分配兼容。我删除了它并添加了一些更明确的检查,现在一切正常了: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 惩罚?