[rules-users] OptaPlanner: score corruption when using insertLogical with custom objects

pvandenbrink pieter.van.den.brink at topicus.nl
Wed Jul 17 05:59:38 EDT 2013


ge0ffrey wrote
> Do you have this issue in 5.4 too? E.g.: the 5.4 equivalent of full 
> assert (TRACE) does not detect score corruption?

I've tried this and actually, yes, it happens with TRACE in 5.4 as well. So
it's not an issue introduced by the upgrade to Beta5, then.


ge0ffrey wrote
> Maybe that "[FamilyEnd Family 11, Timeslot 12, FamilyStart Family 11, 
> Timeslot 7]" exists twice?
> Once way to find out is to put a debug breakpoint at the throw of the 
> exception
> and compare the ConstraintMatchTotal's ConstraintMatch's
> justificationList.

Ok, using the generic changeMoveSelector and swapMoveSelector the error is
almost the same, just a slight difference in timeslot values:

Exception in thread "main" java.lang.IllegalStateException: Score
corruption: the workingScore (0hard/-123soft) is not the uncorruptedScore
(0hard/-120soft) after completedAction (Conversation 24: Family 11, Student
24, Teacher 3, Timeslot 14(Day 3) => Timeslot 14):
  The corrupted scoreDirector has 1 ConstraintMatch(s) which are in excess
(and should not be there):
    defaultpkg/familyCompact/level1/[FamilyEnd Family 11, Timeslot 14,
FamilyStart Family 11, Timeslot 7]=-3
  The corrupted scoreDirector has no ConstraintMatch(s) which are missing.
  Check your score constraints.

I noticed two things:
1) The toString of the move claims it moved the conversation from Timeslot
14 to 14, I think it actually prints the updated timeslot twice, rather than
the original one and the updated one. My own change move had the same issue,
which I fixed by storing the original timeslot of the Conversation in a
separate field of the move and reading from that field in the toString.

2) These two constraint matches exist in the corrupted score map:
defaultpkg/familyCompact/level1/[FamilyEnd Family 11, Timeslot 14,
FamilyStart Family 11, Timeslot 7]=-3
defaultpkg/familyCompact/level1/[FamilyEnd Family 11, Timeslot 14,
FamilyStart Family 11, Timeslot 5]=-5

So there are two different FamilyStarts: (Family 11, Timeslot 7) and (Family
11, Timeslot 5), where there should be only one (the one for timeslot 5).
This causes familyCompact to fire twice for the same family, which explains
the score corruption... But what could cause two FamilyStarts to be
inserted?


ge0ffrey wrote
> 1) But how do Family and Timeslot implement their equals/hashcode?
> My first guess would be to start looking at this.
> 
> 2) There's also the remote probability there's a bug in drools - in 
> which case we'd want a reproducer attached on a jira so we can fix it.

Family, Timeslot and Conversation implement an equals and hashcode based on
their numerical id, like so:

@Override
public boolean equals(Object other)
{
	if ((this == other))
		return true;
	if (!(other instanceof Timeslot))
		return false;
	Timeslot castOther = (Timeslot) other;
	return new EqualsBuilder().append(this.getId(),
castOther.getId()).isEquals();
}

@Override
public int hashCode()
{
	return new HashCodeBuilder().append(getId()).toHashCode();
}




--
View this message in context: http://drools.46999.n3.nabble.com/OptaPlanner-score-corruption-when-using-insertLogical-with-custom-objects-tp4024932p4024965.html
Sent from the Drools: User forum mailing list archive at Nabble.com.


More information about the rules-users mailing list