OptaPlanner 约束流:限制为时间表中的第一个分配
OptaPlanner Constraint Streams: Limiting to First Assignment in a Schedule
我正在设计一项 OptaPlanner 服务,用于优化工业应用中机器人的调度和分配。计划是在线执行的,并且是针对后退的时间范围。有两种类型的传输时间约束(限制机器人移动到机器):一种用于机器人第一次分配给机器,另一种用于随后的每对分配(都在同一台机器上)。
规划在模拟中总体看起来很棒,但在我执行两个不同的运输时间限制的方式中存在一个错误,当我有一个具有多个任务的机器人时会弹出。根本原因是两个约束流的强制执行:
/**
* This constraint enforces a transit time model to keep us from assigning a task prior the earliest possible arrival
* time for the assigned bot. In particular, this method is enforcing arrival time constraints for the very first
* assignment to a bot.
*/
protected Constraint violatingFirstArrivalTime(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(CandidateAssignment.class)
.filter(CandidateAssignment::isAssigned)
.filter(assignment -> !assignment.isCommitted())
.penalizeConfigurable("Respect first arrival time", CandidateAssignment::firstAssignmentTimeliness);
}
/**
* This constraint enforces a transit time model to keep us from assigning a task prior the earliest possible arrival
* time for the assigned bot. In particular, this method is enforcing arrival time constraints for the movement of a
* bot from one task to another.
*/
protected Constraint violatingArrivalTime(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(CandidateAssignment.class)
.filter(CandidateAssignment::isAssigned)
.join(CandidateAssignment.class, equal(CandidateAssignment::getBot))
.penalizeConfigurable("Respect arrival time", CandidateAssignment::taskToTaskTimeliness);
}
特别是,对于针对单个机器人的两个任务,我错误地将“violatingFirstArrivalTime”约束应用于每个任务(不仅仅是第一个) .有什么建议吗?当我立即看到如何实现约束时,我发现约束流很棒,否则令人难以置信的混乱..
我认为 ifNotExists(...)
是您的答案。修改约束,使其仅在该机器人不存在较早的分配时才对分配进行惩罚。
return constraintFactory.forEach(CandidateAssignment.class)
.filter(CandidateAssignment::isAssigned)
.filter(assignment -> !assignment.isCommitted())
.ifNotExists(CandidateAssignment.class,
equal(CandidateAssignment::getBot),
Joiners.filtering((a1, a2) -> {
// Here go all the filters that specify the "comes before" relationship.
// If you can replace filtering() with an actual joiner, even better for performance.
}))
.penalize(...);
我正在设计一项 OptaPlanner 服务,用于优化工业应用中机器人的调度和分配。计划是在线执行的,并且是针对后退的时间范围。有两种类型的传输时间约束(限制机器人移动到机器):一种用于机器人第一次分配给机器,另一种用于随后的每对分配(都在同一台机器上)。
规划在模拟中总体看起来很棒,但在我执行两个不同的运输时间限制的方式中存在一个错误,当我有一个具有多个任务的机器人时会弹出。根本原因是两个约束流的强制执行:
/**
* This constraint enforces a transit time model to keep us from assigning a task prior the earliest possible arrival
* time for the assigned bot. In particular, this method is enforcing arrival time constraints for the very first
* assignment to a bot.
*/
protected Constraint violatingFirstArrivalTime(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(CandidateAssignment.class)
.filter(CandidateAssignment::isAssigned)
.filter(assignment -> !assignment.isCommitted())
.penalizeConfigurable("Respect first arrival time", CandidateAssignment::firstAssignmentTimeliness);
}
/**
* This constraint enforces a transit time model to keep us from assigning a task prior the earliest possible arrival
* time for the assigned bot. In particular, this method is enforcing arrival time constraints for the movement of a
* bot from one task to another.
*/
protected Constraint violatingArrivalTime(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(CandidateAssignment.class)
.filter(CandidateAssignment::isAssigned)
.join(CandidateAssignment.class, equal(CandidateAssignment::getBot))
.penalizeConfigurable("Respect arrival time", CandidateAssignment::taskToTaskTimeliness);
}
特别是,对于针对单个机器人的两个任务,我错误地将“violatingFirstArrivalTime”约束应用于每个任务(不仅仅是第一个) .有什么建议吗?当我立即看到如何实现约束时,我发现约束流很棒,否则令人难以置信的混乱..
我认为 ifNotExists(...)
是您的答案。修改约束,使其仅在该机器人不存在较早的分配时才对分配进行惩罚。
return constraintFactory.forEach(CandidateAssignment.class)
.filter(CandidateAssignment::isAssigned)
.filter(assignment -> !assignment.isCommitted())
.ifNotExists(CandidateAssignment.class,
equal(CandidateAssignment::getBot),
Joiners.filtering((a1, a2) -> {
// Here go all the filters that specify the "comes before" relationship.
// If you can replace filtering() with an actual joiner, even better for performance.
}))
.penalize(...);