public void insertInTrailingEntityMap( PlanningVariableDescriptor variableDescriptor, Object entity) { if (hasChainedVariables && variableDescriptor.isChained()) { Map<Object, Set<Object>> valueToTrailingEntityMap = trailingEntitiesMap.get(variableDescriptor); if (valueToTrailingEntityMap == null) { throw new IllegalStateException( "The ScoreDirector (" + getClass() + ") is bugged," + " because the chained planningVariable (" + variableDescriptor.getVariableName() + ") was not found in the trailingEntitiesMap."); } Object value = variableDescriptor.getValue(entity); Set<Object> trailingEntities = valueToTrailingEntityMap.get(value); if (trailingEntities == null) { trailingEntities = Collections.newSetFromMap(new IdentityHashMap<Object, Boolean>()); valueToTrailingEntityMap.put(value, trailingEntities); } boolean addSucceeded = trailingEntities.add(entity); if (!addSucceeded) { throw new IllegalStateException( "The ScoreDirector (" + getClass() + ") is corrupted," + " because the entity (" + entity + ") for chained planningVariable (" + variableDescriptor.getVariableName() + ") cannot be inserted: it was already inserted."); } } }
private void retractFromTrailingEntityMap(Object entity) { if (hasChainedVariables) { for (Map.Entry<PlanningVariableDescriptor, Map<Object, Set<Object>>> entry : chainedVariableToTrailingEntitiesMap.entrySet()) { PlanningVariableDescriptor variableDescriptor = entry.getKey(); if (variableDescriptor.getPlanningEntityDescriptor().appliesToPlanningEntity(entity)) { Object value = variableDescriptor.getValue(entity); Map<Object, Set<Object>> valueToTrailingEntityMap = entry.getValue(); Set<Object> trailingEntities = valueToTrailingEntityMap.get(value); boolean removeSucceeded = trailingEntities != null && trailingEntities.remove(entity); if (!removeSucceeded) { throw new IllegalStateException( "The ScoreDirector (" + getClass() + ") is corrupted," + " because the entity (" + entity + ") for chained planningVariable (" + variableDescriptor.getVariableName() + ") cannot be retracted: it was never inserted."); } if (trailingEntities.isEmpty()) { valueToTrailingEntityMap.put(value, null); } } } } }
public void retractFromTrailingEntityMap( PlanningVariableDescriptor variableDescriptor, Object entity) { if (hasChainedVariables && variableDescriptor.isChained()) { Map<Object, Set<Object>> valueToTrailingEntityMap = trailingEntitiesMap.get(variableDescriptor); if (valueToTrailingEntityMap == null) { throw new IllegalStateException( "The ScoreDirector (" + getClass() + ") is bugged," + " because the chained planningVariable (" + variableDescriptor.getVariableName() + ") was not found in the trailingEntitiesMap."); } Object value = variableDescriptor.getValue(entity); Set<Object> trailingEntities = valueToTrailingEntityMap.get(value); boolean removeSucceeded = trailingEntities != null && trailingEntities.remove(entity); if (!removeSucceeded) { throw new IllegalStateException( "The ScoreDirector (" + getClass() + ") is corrupted," + " because the entity (" + entity + ") for chained planningVariable (" + variableDescriptor.getVariableName() + ") cannot be retracted: it was never inserted."); } if (trailingEntities.isEmpty()) { valueToTrailingEntityMap.put(value, null); } } }
private void insertInTrailingEntityMap(Object entity) { if (hasChainedVariables) { for (Map.Entry<PlanningVariableDescriptor, Map<Object, Set<Object>>> entry : chainedVariableToTrailingEntitiesMap.entrySet()) { PlanningVariableDescriptor variableDescriptor = entry.getKey(); if (variableDescriptor.getPlanningEntityDescriptor().appliesToPlanningEntity(entity)) { Object value = variableDescriptor.getValue(entity); Map<Object, Set<Object>> valueToTrailingEntityMap = entry.getValue(); Set<Object> trailingEntities = valueToTrailingEntityMap.get(value); if (trailingEntities == null) { trailingEntities = Collections.newSetFromMap(new IdentityHashMap<Object, Boolean>()); valueToTrailingEntityMap.put(value, trailingEntities); } boolean addSucceeded = trailingEntities.add(entity); if (!addSucceeded) { throw new IllegalStateException( "The ScoreDirector (" + getClass() + ") is corrupted," + " because the entity (" + entity + ") for chained planningVariable (" + variableDescriptor.getVariableName() + ") cannot be inserted: it was already inserted."); } } } } }
private ValueSelector buildBaseValueSelector( EnvironmentMode environmentMode, PlanningVariableDescriptor variableDescriptor, SelectionCacheType minimumCacheType, boolean randomSelection) { if (variableDescriptor.getValueRangeDescriptor().isEntityDependent()) { FromEntityPropertyPlanningValueRangeDescriptor valueRangeDescriptor = (FromEntityPropertyPlanningValueRangeDescriptor) variableDescriptor.getValueRangeDescriptor(); // TODO should we ignore the minimumCacheType so it can be cached on changeMoves too? return new FromEntityPropertyValueSelector( valueRangeDescriptor, minimumCacheType, randomSelection); } else { // FromSolutionPropertyValueSelector caches by design, so it uses the minimumCacheType if (variableDescriptor.isPlanningValuesCacheable()) { if (minimumCacheType.compareTo(SelectionCacheType.PHASE) < 0) { // TODO we probably want to default this to SelectionCacheType.JUST_IN_TIME minimumCacheType = SelectionCacheType.PHASE; } } else { if (minimumCacheType.compareTo(SelectionCacheType.STEP) < 0) { // TODO we probably want to default this to SelectionCacheType.JUST_IN_TIME minimumCacheType = SelectionCacheType.STEP; } } return new FromSolutionPropertyValueSelector( variableDescriptor, minimumCacheType, randomSelection); } }
public void insertInTrailingEntityMap(PlanningEntityDescriptor entityDescriptor, Object entity) { if (hasChainedVariables) { for (PlanningVariableDescriptor variableDescriptor : entityDescriptor.getVariableDescriptors()) { if (variableDescriptor.isChained()) { insertInTrailingEntityMap(variableDescriptor, entity); } } } }
public ConstructionHeuristicMoveScope nominateMove(ConstructionHeuristicStepScope stepScope) { Object entity = stepScope.getEntity(); if (!reinitializeVariableEntityFilter.accept(stepScope.getScoreDirector(), entity)) { return null; } // TODO extract to PlacerForager Score maxScore = null; ConstructionHeuristicMoveScope nominatedMoveScope = null; int moveIndex = 0; for (Iterator it = valueSelector.iterator(entity); it.hasNext(); ) { Object value = it.next(); ConstructionHeuristicMoveScope moveScope = new ConstructionHeuristicMoveScope(stepScope); moveScope.setMoveIndex(moveIndex); Move move; if (variableDescriptor.isChained()) { move = new ChainedChangeMove(entity, variableDescriptor, value); } else { move = new ChangeMove(entity, variableDescriptor, value); } moveScope.setMove(move); if (!move.isMoveDoable(stepScope.getScoreDirector())) { logger.trace( " Move index ({}) not doable, ignoring move ({}).", moveScope.getMoveIndex(), move); } else { doMove(moveScope); // TODO extract to PlacerForager if (maxScore == null || moveScope.getScore().compareTo(maxScore) > 0) { maxScore = moveScope.getScore(); // TODO for non explicit Best Fit *, default to random picking from a maxMoveScopeList nominatedMoveScope = moveScope; } if (moveIndex >= selectedCountLimit) { break; } } moveIndex++; if (termination.isPhaseTerminated(stepScope.getPhaseScope())) { break; } } return nominatedMoveScope; }
public Object getTrailingEntity( PlanningVariableDescriptor chainedVariableDescriptor, Object planningValue) { Set<Object> trailingEntities = trailingEntitiesMap.get(chainedVariableDescriptor).get(planningValue); if (trailingEntities == null) { return null; } // trailingEntities can never be an empty list if (trailingEntities.size() > 1) { throw new IllegalStateException( "The planningValue (" + planningValue + ") has multiple trailing entities (" + trailingEntities + ") pointing to it for chained planningVariable (" + chainedVariableDescriptor.getVariableName() + ")."); } return trailingEntities.iterator().next(); }
public ValuePlacer(Termination termination, ValueSelector valueSelector, int selectedCountLimit) { this.termination = termination; this.valueSelector = valueSelector; variableDescriptor = valueSelector.getVariableDescriptor(); reinitializeVariableEntityFilter = variableDescriptor.getReinitializeVariableEntityFilter(); this.selectedCountLimit = selectedCountLimit; solverPhaseLifecycleSupport.addEventListener(valueSelector); // TODO don't use Integer.MAX_VALUE as a magical value if (valueSelector.isNeverEnding() && selectedCountLimit == Integer.MAX_VALUE) { throw new IllegalStateException( "The placer (" + this + ") with selectedCountLimit (" + selectedCountLimit + ") has valueSelector (" + valueSelector + ") with neverEnding (" + valueSelector.isNeverEnding() + ")."); } }
protected boolean isBaseInherentlyCached(PlanningVariableDescriptor variableDescriptor) { return !variableDescriptor.getValueRangeDescriptor().isEntityDependent(); }