timefold-solver
timefold-solver copied to clipboard
VariableListener corruption: Impossible VariableListener corruption(-1hard)…but all shadow variables is the same …
Describe the bug I think I set the variable listener trigger order correctly, and defined a seemly correct constraint.but it told me I have a variable listener corruption.
To Reproduce
This is my Assign class
@PlanningEntity
public class Assign extends AbstractPersistable{
@PlanningVariable(valueRangeProviderRefs = "customerList",nullable = true)
protected Customer customer;
@PlanningVariable(valueRangeProviderRefs = "serverStationList",nullable = true)
protected ServerStation station;
@PlanningVariable(valueRangeProviderRefs = "demandChoices",nullable = true)
protected Long assignedDemand;
...
}
----------------------------
This is my Customer class
@PlanningEntity
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Customer extends AbstractPersistable{
protected long maxDemand;
protected Location location;
/**
* 需求等级,对应服务站可服务等级。没确定上限,按越高越好
*/
protected int demandLevel;
@InverseRelationShadowVariable(sourceVariableName = "customer")
@Schema(hidden = true)
protected List<Assign> assignedStations=new ArrayList<>();
@ShadowVariable(sourceEntityClass = Customer.class,sourceVariableName = "assignedStations",variableListenerClass = RemainingDemandListener.class)
// @Schema(hidden = true)
protected Long remainingDemand;
…
}
There is also a ServerStation class (Omitted)
Now this is key parts in my RemainingDemandListener.class
@Override
public void afterVariableChanged(ScoreDirector<FacilityLocationSolution> scoreDirector, Customer customer) {
updateRemainingDemand(scoreDirector, customer);
}
private void updateRemainingDemand(ScoreDirector<FacilityLocationSolution> scoreDirector, Customer customer){
// if(customer==null){
// return;
// }
long remainingDemand=customer.getMaxDemand();
for (Assign assign : customer.getAssignedStations()) {
if(assign.getStation()!=null && assign.getAssignedDemand()!=null){
remainingDemand-=assign.getAssignedDemand();
}
}
remainingDemand=remainingDemand<0?0:remainingDemand;
scoreDirector.beforeVariableChanged(customer, "remainingDemand");
customer.setRemainingDemand(remainingDemand);
scoreDirector.afterVariableChanged(customer, "remainingDemand");
}
Finally, my constraints about this variable:
Constraint noRestDemand(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Customer.class)
.filter(c->c.getRemainingDemand()!=0)
.penalizeConfigurable()
.asConstraint(FacilityLocationConstraintConfig.NO_REST_DEMAND);
}
Environment
timefold 1.3:
Output of java -version:17
Output of uname -a or ver:
Additional information
Provide any and all other information which might be relevant to the issue.
Thanks for reporting, @maker2020! Please provide runnable code for us to reproduce the problem, otherwise there isn't much we could do.
problem.zip this is my code of this module, you mean a runnable code, should I upload all maven project? @triceo
Yes, a Maven project would be ideal.
timefold-demo.zip ok, this is a maven project, you can run Main.java,then the problem reproduce. thanks for your patience @triceo