【问题标题】:How to combine multiple planning entities for solving one problem in OptaPlanner?如何组合多个规划实体来解决 OptaPlanner 中的一个问题?
【发布时间】:2022-08-12 20:30:42
【问题描述】:

鉴于:

Employee {
    int id;
    int minJobNum;
    int maxJobNum;
    int totalWorkTime;

    @OneToMany
    List<Job> jobs;

    @ManyToOne
    Vehicle vehicle;
}

@PlanningEntity
Job {
    @PlanningId
    int id;

    @ManyToOne
    Employee employee;

    @PlanningVariable(valueRangeProviderRefs = \"employeeRange\")
    private Employee employee;
}

@PlanningEntity
Vehicle {
    @PlanningId
    int id;
    int capacity;

    @OneToMany
    @PlanningListVariable(valueRangeProviderRefs = \"employeeRange\")
    List<Employee> employees;
}

成本矩阵:

List<Cost> costs;

Cost {

    Job from;
    Job to;
    Long time;

}

这是主要课程:

SolverFactory<Solution> solverFactory = SolverFactory.create(new SolverConfig()
        .withSolutionClass(Solution.class)
        .withEntityClasses(Job.class, Vehicle.class)
        .withConstraintProviderClass(SolutionConstraintProvider.class)
        .withTerminationSpentLimit(Duration.ofSeconds(5)));

Solution problem = generateDemoData();

Solver<Solution> solver = solverFactory.buildSolver();
Solution solution = solver.solve(problem);

ScoreManager<Solution, HardMediumSoftScore> scoreManager = ScoreManager.create(solverFactory);
ScoreExplanation<Solution, HardMediumSoftScore> scoreExplanation = scoreManager.explainScore(solution);
System.out.println(scoreExplanation.getSummary());
System.out.println(\"Is Feasible: \" + scoreExplanation.getScore().isFeasible());

我的约束:

public class SolutionConstraintProvider implements ConstraintProvider {

    @Override
    public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
        return new Constraint[]{
                minJobNumberConflict(constraintFactory),
                maxJobNumberConflict(constraintFactory),
                vehicleCapacity(constraintFactory),
                vehicleMaxCapacity(constraintFactory)
        };
    }

    private Constraint minJobNumberConflict(ConstraintFactory constraintFactory) {
        return constraintFactory.forEach(Job.class).groupBy(Job::getEmployee, count())
                .filter((employee, count) -> 10 > count)
                .penalize(\"minJobNumberConflict\",
                        HardMediumSoftScore.ONE_MEDIUM, (employee, count) -> 10 - count);
    }

    private Constraint maxJobNumberConflict(ConstraintFactory constraintFactory) {
        return constraintFactory.forEach(Job.class).groupBy(Job::getEmployee, count())
                .filter((employee, count) -> count > 30)
                .penalize(\"maxJobNumberConflict\",
                        HardMediumSoftScore.ONE_HARD, (employee, count) -> count - 30);
    }

    private Constraint vehicleMaxCapacity(ConstraintFactory factory) {
        return factory.forEach(Vehicle.class)
                .filter(vehicle -> vehicle.getEmployeeList().size() > vehicle.getCapacity())
                .penalizeLong(\"vehicleMaxCapacity\",
                        HardMediumSoftLongScore.ONE_HARD, vehicle -> vehicle.getEmployeeList().size() - vehicle.getCapacity());
    }

    private Constraint vehicleCapacity(ConstraintFactory factory) {
        return factory.forEach(Vehicle.class)
                .filter(vehicle -> !vehicle.getEmployeeList().isEmpty())
                .filter(vehicle -> vehicle.getEmployeeList().size() < vehicle.getCapacity())
                .penalizeLong(\"vehicleCapacityConflict\",
                        HardMediumSoftLongScore.ONE_SOFT, vehicle -> vehicle.getCapacity() - vehicle.getEmployeeList().size());
    }

}

我的解决方案类:

@PlanningSolution
public class Solution {

    @ProblemFactCollectionProperty
    @ValueRangeProvider(id = \"employeeRange\")
    private List<Employee> employees;

    @PlanningEntityCollectionProperty
    private List<Vehicle> vehicles;

    @PlanningEntityCollectionProperty
    private List<Job> jobs;

    @PlanningScore
    private HardMediumSoftScore score;

    public Plan(List<Employee> employees, List<Job> applications, List<Vehicle> vehicles) {
        this.employees = employees;
        this.jobs = jobs;
        this.vehicles = vehicles;
    }

}
  • 每个员工都有一个最小和最大工作编号。例如,每个员工必须做 10 份以上的工作,少于 30 份。
  • 每辆车都有容量。 Еhe 员工人数不应超过车辆容量
  • 每个作业都有一个地址和一个坐标。
  • 另外,对于每对工作(地址),都有一个到达点的时间(成本矩阵)。
  • 总时间(考虑到到达路线的时间和完成每项工作的时间为20分钟)不应超过员工的totalWorkTime;

当我尝试运行代码时,出现以下错误:

entityClass(Vehicle 类)有一个 @PlanningVariable 注释属性(employeeList),它引用了一个 @ValueRangeProvider 注释成员(字段私有 java.util.List Solution.employees),该成员返回一个 Collection,其元素类型(Employee 类)不能被分配给@PlanningVariable\ 的类型(接口java.util.List)。

  • 这不是一个好问题。你试过什么了?你遇到了什么问题?阅读optaplanner.org/docs/optaplanner/latest/planner-configuration/… 了解规划领域建模。想想你希望 OptaPlanner 在求解过程中改变什么(这将是你的计划变量,可能不止一个)。关于您的问题定义,我不明白的是,您想如何使用车辆运送多个工人,每个工人从事不同的工作?
  • 我可以解决员工上下班的问题,也可以解决员工个人分工的问题。但是不可能将它们组合成一个代码以便一起计算。我将很快更新我的问题并添加我添加的解决方案。多谢
  • 我已经更新了这个问题并添加了更多信息来澄清这个问题。我希望你能提出一个解决这个问题的方法。先感谢您)

标签: java optaplanner


【解决方案1】:

具有多个规划实体类的良好用例很少见。它们需要定制动作,这使它们成为劳动密集型的。我们正在努力提高它的易用性。

但是,在大多数情况下,最好还是做多阶段规划,商业智慧. I think I discussed that in this video.康威定律等

【讨论】:

    猜你喜欢
    • 2011-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    相关资源
    最近更新 更多