[英]How to choose a vehicle that can accommodate the specified number of employees with OptaPlanner?
如何使用 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 的傳輸,后者更優化。
如何正確解決這個問題? 提前致謝
問題是該算法選擇了最先出現並滿足給定限制的傳輸。
這就是構建啟發式算法的工作原理。 它的目標是快速找到一個足夠好的解決方案,可以在下一階段進一步優化,稱為本地搜索。
現在,如果您考慮將 6 名員工分配給容量為 6 的交通工具比容量為 20 的交通工具更好,那么您必須為 OptaPlanner 提供激勵以進行改進。
這些激勵以約束的形式表現出來。 在這種情況下,您可以定義一個約束,為每個使用的傳輸上的未使用容量添加軟評分懲罰。
使用大小為 20 的傳輸可能會導致得分為0hard/-14soft
,而使用大小為 6 的傳輸會導致得分為 0hard 0hard/0soft
,這樣更好。
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());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.