// TODO remove this method and use the SingletonInverseVariableSupply directly public Object getTrailingEntity( GenuineVariableDescriptor chainedVariableDescriptor, Object planningValue) { SingletonInverseVariableSupply supply = variableListenerSupport.demand( new SingletonInverseVariableDemand(chainedVariableDescriptor)); return supply.getInverseSingleton(planningValue); }
public boolean isMoveDoable(ScoreDirector scoreDirector) { Object leftValue = variableDescriptor.getValue(leftEntity); Object rightEntity = inverseVariableSupply.getInverseSingleton(rightValue); if (ObjectUtils.equals(leftValue, rightValue) || ObjectUtils.equals(leftEntity, rightValue) || ObjectUtils.equals(rightEntity, leftValue)) { return false; } if (rightEntity == null) { Object leftAnchor = anchorVariableSupply.getAnchor(leftEntity); Object rightAnchor = determineRightAnchor(); // TODO Currently unsupported because we fail to create a valid undoMove... even though doMove // supports it if (leftAnchor == rightAnchor) { return false; } } if (!variableDescriptor.isValueRangeEntityIndependent()) { ValueRangeDescriptor valueRangeDescriptor = variableDescriptor.getValueRangeDescriptor(); Solution workingSolution = scoreDirector.getWorkingSolution(); if (rightEntity != null) { ValueRange rightValueRange = valueRangeDescriptor.extractValueRange(workingSolution, rightEntity); if (!rightValueRange.contains(leftValue)) { return false; } } ValueRange leftValueRange = valueRangeDescriptor.extractValueRange(workingSolution, leftEntity); if (!leftValueRange.contains(rightValue)) { return false; } } return true; }
protected Object findLastEntityInChainOrLeftEntity() { Object entity = rightValue; while (entity != leftEntity) { Object nextEntity = inverseVariableSupply.getInverseSingleton(entity); if (nextEntity == null) { return entity; } entity = nextEntity; } return leftEntity; }
public String toString() { Object leftValue = variableDescriptor.getValue(leftEntity); Object rightEntity = inverseVariableSupply.getInverseSingleton(rightValue); return leftEntity + " {" + leftValue + "} <-tailChainSwap-> " + rightEntity + " {" + rightValue + "}"; }
@Override protected void doMoveOnGenuineVariables(ScoreDirector scoreDirector) { Object leftAnchor = anchorVariableSupply.getAnchor(leftEntity); Object rightAnchor = determineRightAnchor(); Object leftValue = variableDescriptor.getValue(leftEntity); Object rightEntity = inverseVariableSupply.getInverseSingleton(rightValue); // Sometimes null if (leftAnchor != rightAnchor) { // Change the left entity scoreDirector.changeVariableFacade(variableDescriptor, leftEntity, rightValue); // Change the right entity if (rightEntity != null) { scoreDirector.changeVariableFacade(variableDescriptor, rightEntity, leftValue); } } else { Object lastEntityInChainOrLeftEntity = findLastEntityInChainOrLeftEntity(); if (lastEntityInChainOrLeftEntity == leftEntity) { // Reverses loop on the side that doesn't include the anchor, because rightValue is earlier // than leftEntity Object leftNextEntity = inverseVariableSupply.getInverseSingleton(leftEntity); scoreDirector.changeVariableFacade(variableDescriptor, leftEntity, rightValue); reverseChain(scoreDirector, leftValue, leftEntity, rightEntity); if (leftNextEntity != null) { scoreDirector.changeVariableFacade(variableDescriptor, leftNextEntity, rightEntity); } } else { // Reverses loop on the side that does include the anchor, because rightValue is later than // leftEntity Object lastEntityInChain = lastEntityInChainOrLeftEntity; Object leftNextEntity = inverseVariableSupply.getInverseSingleton(leftEntity); Object entityAfterAnchor = inverseVariableSupply.getInverseSingleton(leftAnchor); // Change the head of the chain reverseChain(scoreDirector, leftValue, leftEntity, entityAfterAnchor); // Change leftEntity scoreDirector.changeVariableFacade(variableDescriptor, leftEntity, rightValue); // Change the tail of the chain reverseChain(scoreDirector, lastEntityInChain, leftAnchor, rightEntity); scoreDirector.changeVariableFacade(variableDescriptor, leftNextEntity, rightEntity); } } }
public Move createUndoMove(ScoreDirector scoreDirector) { Object leftAnchor = anchorVariableSupply.getAnchor(leftEntity); Object rightAnchor = determineRightAnchor(); Object leftValue = variableDescriptor.getValue(leftEntity); if (leftAnchor != rightAnchor) { return new TailChainSwapMove( variableDescriptor, inverseVariableSupply, anchorVariableSupply, leftEntity, leftValue); } else { Object rightEntity = inverseVariableSupply.getInverseSingleton(rightValue); if (rightEntity != null) { return new TailChainSwapMove( variableDescriptor, inverseVariableSupply, anchorVariableSupply, rightEntity, rightValue); } else { // TODO Currently unsupported because we fail to create a valid undoMove... even though // doMove supports it throw new IllegalStateException( "Impossible state, because isMoveDoable() should not return true."); } } }
public Collection<? extends Object> getPlanningEntities() { Object rightEntity = inverseVariableSupply.getInverseSingleton(rightValue); return Arrays.asList(leftEntity, rightEntity); }