Im using Optaplanner/Timefold to solve a allocation problem.
I must allocate orders in vehicles with certain restrictions. This part its very similar to the cloud process distributions and its working well with the following structure: @PlanningEntity Order contains a @PlanningVariable vehicle.
However, exists another restriction: i must have avaiable stock for each allocated order. Now it is being handle usind a map (material of the order is the key and the amount of boxes avaible is the value) inside of the Solution. Multiple orders can consume the same stock and all of them need to be taken into account. I have many orders and each one has a product. Each order may require different numbers of boxes.
@PlanningEntity Order{
Product product;
Integer amountOfBoxes;
@PlanningVariable(nullable)
Vehicle vehicle;
}
@Solution Solution{
@PlanningEntityCollectionProperty
List<Order> orders;
@ProblemFactCollectionPropert
List<Vehicle> vehicles;
Map<Product, Integer> stock;
}
Is there any another way to work with the stock?
I was trying with ValueRangeProviders but i couldn't get anywhere.
You can implement your Product as class/problem fact with current stock level as class attribute. After that you can implement constraint to check stock levels and penalize if below zero. Something like
return factory.forEach(Order.class)
.groupBy(Order::getProduct, sum(Order::getAmountOfBoxes))
.filter((product, amount) -> product.getAvailableStock() > amount)
.penalize(HardSoftScore.ONE_HARD, (product, amount) -> amount - product.getAvailableStock())
.asConstraint("Not enougth stock level")