簡體   English   中英

如何使用 OptaPlanner 選擇可以容納指定數量員工的車輛?

[英]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, 4, 6, 2
  • 員工 - 6

問題是該算法選擇了最先出現並滿足給定限制的傳輸。 例如,為了解決這個問題,算法選擇容量為 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM