如何选择能够容纳有OptaPlanner的指定数量的员工的车辆?
雇员:
public class Employee {
@PlanningId
private Long id;
private String name;
}运输(车辆)
@PlanningEntity
public class Transport {
@PlanningId
private Long id;
private Integer capacity;
@PlanningListVariable(valueRangeProviderRefs = "employeeRange")
private List<Employee> employeeList = new ArrayList<>();
}解决方案
@PlanningSolution
public class Solution {
@PlanningEntityCollectionProperty
private List<Transport> transports;
@ProblemFactCollectionProperty
@ValueRangeProvider(id = "employeeRange")
private List<Employee> employees;
@PlanningScore
private HardMediumSoftLongScore score;
public Plan(List<Transport> transports, List<Employee> employees) {
this.transports = transports;
this.employees = employees;
}
}约束
private Constraint transportCapacity(ConstraintFactory factory) {
return factory.forEach(Transport.class)
.filter(transport -> transport.getEmployees().size() > transport.getCapacity()).penalizeLong("capacity",
HardMediumSoftLongScore.ONE_HARD, transport -> transport.getEmployees().size() - transport.getCapacity());
}给予:
问题是,该算法选择优先的传输,并满足给定的限制。例如,为了解决这个问题,算法选择了容量为20而不是6的传输方式,这是最优的。
如何正确解决这个问题?提前感谢!
发布于 2022-07-25 07:38:55
问题是,算法首先选择了满足给定限制的传输方式。
这就是构造启发式算法的工作原理。它的目标是快速,找到一个足够好的解决方案,可以在下一个阶段进行进一步优化,称为Local。
现在,如果您考虑将6名员工分配给容量为6的运输而不是容量为20的运输,则必须为OptaPlanner提供奖励以使其得到改进。
这些激励措施是以限制的形式表达的。在这种情况下,您可以定义一个约束,为每个已用传输的未使用容量添加一个软分数损失。
使用尺寸为20的传输可以得到0hard/-14soft的分数,而使用6大小的传输将导致0hard/0soft,这是更好的。
发布于 2022-07-25 15:53:04
根据yurloc的答案,我们可以添加两个约束:
private Constraint transportMaxCapacity(ConstraintFactory factory) {
return factory.forEach(Transport.class)
.filter(transport -> transport.getEmployees().size() > transport.getCapacity())
.penalizeLong("max capacity conflict",
HardMediumSoftLongScore.ONE_HARD, transport -> transport.getEmployees().size() - transport.getCapacity());
}
private Constraint transportCapacity(ConstraintFactory factory) {
return factory.forEach(Transport.class)
.filter(transport -> !transport.getEmployees().isEmpty())
.filter(transport -> transport.getEmployees().size() < transport.getCapacity())
.penalizeLong("optimal placement conflict",
HardMediumSoftLongScore.ONE_SOFT, transport -> transport.getCapacity() - transport.getInspectorList().size());
}https://stackoverflow.com/questions/73105237
复制相似问题