I have to plan a list of orders into machines.
The relation order machine is by item code. If the machine has the order item code the machine can mange the order so the order can be assigned to the machine.
It could happen that some orders have an item code that don't match with any machine.
This is my code:
@PlanningEntity
public class Machine {
private List<Order> m_plannedOrders;
...
@PlanningListVariable
public List<Order> getPlannedOrders() {
return m_plannedOrders;
}
public void setPlannedOrders(List<Order> orders) {
m_plannedOrders = orders;
}
...
public boolean canManage(String itemCode) {
return true if this machine can handle the order by code.
}
}
@PlanningEntity
public class Order {
private Machine m_machine;
...
@InverseRelationShadowVariable(sourceVariableName = "plannedOrders")
public Machine getMachine() {
return m_machine;
}
public void setMachine(Machine machine) {
m_machine = machine;
}
public boolean isValidMachine() {
boolean retVal = false;
if (m_machine != null) {
retVal = m_machine.canManage(m_itemCode);
}
return retVal;
}
}
@PlanningSolution
public class MachineOrdersPlanning {
...
@PlanningEntityCollectionProperty
public List<Machine> getMachines() {
return m_machines;
}
@ValueRangeProvider
@ProblemFactCollectionProperty
public List<Order> getOrders() {
return m_orders;
}
@PlanningScore
public HardSoftScore getScore() {
return m_score;
}
}
The constraints I use is:
private Constraint orderOnCorrectMachine(ConstraintFactory constraintFactory) {
return constraintFactory
.forEach(Order.class)
.filter(order -> order.getMachine() == null || !order.isValidMachine())
.penalize(HardSoftScore.ONE_HARD).asConstraint("Order assigned to valid machine");
}
I tried also without order.getMachine() == null ||
The problem is that for instante for Machine 1 the output is
Machine: 1
Order 29 canManaged? true
Order 18 canManaged? true
Order 16 canManaged? true
Order 15 canManaged? true
Order 14 canManaged? true
Order 9 canManaged? true
Order 8 canManaged? true
Order 6 canManaged? false
Order 4 canManaged? true
Order 6 is assigned to a machine because the planning variable cannot be null. But the InverseRelationshadowVariable does not accept nullable in annotation.
What I desire is that all unmanageable orders will not assigned. Do I have to work with nullable in annotation somewhere or I have to change the constraint or what else?
Any help is appreciated.
Simple (may be not optimal) approach will be to create an extra "dummy" machine capable to handle any type of order and work with HardMediumScore and two constraints:
You can still use the soft score for you soft rules.