How to choose a vehicle that can accommodate the specified number of employees with OptaPlanner?
Employee:
public class Employee {
@PlanningId
private Long id;
private String name;
}
Transport (Vehicle)
@PlanningEntity
public class Transport {
@PlanningId
private Long id;
private Integer capacity;
@PlanningListVariable(valueRangeProviderRefs = "employeeRange")
private List<Employee> employeeList = new ArrayList<>();
}
Solution
@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;
}
}
Constraint
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());
}
Given:
- transports with capacity - 20, 4, 6, 2
- employees - 6
The problem is that the algorithm chooses the transport that comes first and meets the given restrictions. For example, for solving this problem algorithm chooses transport with capacity 20 instead of 6 which is more optimal.
How to solve this problem correctly? Thanks in advance!