Reputation: 67
Given:
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;
}
cost matrix:
List<Cost> costs;
Cost {
Job from;
Job to;
Long time;
}
Here is the main class:
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());
My Constraints:
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());
}
}
My Solution class:
@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;
}
}
When i try to run the code i get the following error:
The entityClass (class Vehicle) has a @PlanningVariable annotated property (employeeList) that refers to a @ValueRangeProvider annotated member (field private java.util.List Solution.employees) that returns a Collection with elements of type (class Employee) which cannot be assigned to the @PlanningVariable's type (interface java.util.List).
Upvotes: 0
Views: 470
Reputation: 27337
Good use cases with multiple planning entity classes are rare. They require custom moves, which makes them labor intensive. We are working on improving the easy of use of that though.
However, in most cases, it's better to do multi-stage planning instead, business wise. I think I discussed that in this video. Conway's law etc.
Upvotes: 1