根据Optaplanner文档实现不可移动的实体时,我得到了UnsupportedOperationException。我使用的是6.4.0版本。
我的实体:
@PlanningEntity(difficultyComparatorClass=AssignmentCreditHoursComparator.class, movableEntitySelectionFilter=ImmovableChangeMoveFilter.class) public class Assignment{...}
我的过滤器
public class ImmovableChangeMoveFilter implements SelectionFilter<Assignment> {
@Override
public boolean accept(ScoreDirector scoreDirector, Assignment a) {
if(a.isLocked())
return false;
else
return true;
}
}
例外:
Exception in thread "main" java.lang.UnsupportedOperationException
at org.optaplanner.core.impl.heuristic.selector.entity.decorator.FilteringEntitySelector.listIterator(FilteringEntitySelector.java:125)
at org.optaplanner.core.impl.heuristic.selector.common.iterator.AbstractOriginalSwapIterator.<init>(AbstractOriginalSwapIterator.java:49)
at org.optaplanner.core.impl.heuristic.selector.move.generic.SwapMoveSelector$1.<init>(SwapMoveSelector.java:129)
at org.optaplanner.core.impl.heuristic.selector.move.generic.SwapMoveSelector.iterator(SwapMoveSelector.java:129)
at org.optaplanner.core.impl.heuristic.selector.move.decorator.AbstractCachingMoveSelector.constructCache(AbstractCachingMoveSelector.java:76)
at org.optaplanner.core.impl.heuristic.selector.common.SelectionCacheLifecycleBridge.phaseStarted(SelectionCacheLifecycleBridge.java:49)
at org.optaplanner.core.impl.phase.event.PhaseLifecycleSupport.firePhaseStarted(PhaseLifecycleSupport.java:39)
at org.optaplanner.core.impl.heuristic.selector.AbstractSelector.phaseStarted(AbstractSelector.java:47)
at org.optaplanner.core.impl.phase.event.PhaseLifecycleSupport.firePhaseStarted(PhaseLifecycleSupport.java:39)
at org.optaplanner.core.impl.heuristic.selector.AbstractSelector.phaseStarted(AbstractSelector.java:47)
at org.optaplanner.core.impl.phase.event.PhaseLifecycleSupport.firePhaseStarted(PhaseLifecycleSupport.java:39)
at org.optaplanner.core.impl.heuristic.selector.AbstractSelector.phaseStarted(AbstractSelector.java:47)
at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.phaseStarted(LocalSearchDecider.java:97)
at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.phaseStarted(DefaultLocalSearchPhase.java:122)
at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(DefaultLocalSearchPhase.java:66)
at org.optaplanner.core.impl.solver.DefaultSolver.runPhases(DefaultSolver.java:215)
at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:176)
这取自Optaplanner代码......
public class FilteringEntitySelector extends AbstractEntitySelector {
protected final EntitySelector childEntitySelector;
protected final List<SelectionFilter> filterList;
protected final boolean bailOutEnabled;
protected ScoreDirector scoreDirector = null;
public FilteringEntitySelector(EntitySelector childEntitySelector, List<SelectionFilter> filterList) {
this.childEntitySelector = childEntitySelector;
this.filterList = filterList;
bailOutEnabled = childEntitySelector.isNeverEnding();
phaseLifecycleSupport.addEventListener(childEntitySelector);
}
// ************************************************************************
// Worker methods
// ************************************************************************
@Override
public void phaseStarted(AbstractPhaseScope phaseScope) {
super.phaseStarted(phaseScope);
scoreDirector = phaseScope.getScoreDirector();
}
@Override
public void phaseEnded(AbstractPhaseScope phaseScope) {
super.phaseEnded(phaseScope);
scoreDirector = null;
}
public EntityDescriptor getEntityDescriptor() {
return childEntitySelector.getEntityDescriptor();
}
public boolean isCountable() {
return childEntitySelector.isCountable();
}
public boolean isNeverEnding() {
return childEntitySelector.isNeverEnding();
}
public long getSize() {
return childEntitySelector.getSize();
}
public Iterator<Object> iterator() {
return new JustInTimeFilteringEntityIterator(childEntitySelector.iterator());
}
protected class JustInTimeFilteringEntityIterator extends UpcomingSelectionIterator<Object> {
private final Iterator<Object> childEntityIterator;
private final long bailOutSize;
public JustInTimeFilteringEntityIterator(Iterator<Object> childEntityIterator) {
this.childEntityIterator = childEntityIterator;
this.bailOutSize = determineBailOutSize();
}
@Override
protected Object createUpcomingSelection() {
Object next;
long attemptsBeforeBailOut = bailOutSize;
do {
if (!childEntityIterator.hasNext()) {
return noUpcomingSelection();
}
if (bailOutEnabled) {
// if childEntityIterator is neverEnding and nothing is accepted, bail out of the infinite loop
if (attemptsBeforeBailOut <= 0L) {
logger.warn("Bailing out of neverEnding selector ({}) to avoid infinite loop.",
FilteringEntitySelector.this);
return noUpcomingSelection();
}
attemptsBeforeBailOut--;
}
next = childEntityIterator.next();
} while (!accept(scoreDirector, next));
return next;
}
}
protected long determineBailOutSize() {
if (!bailOutEnabled) {
return -1L;
}
return childEntitySelector.getSize() * 10L;
}
public ListIterator<Object> listIterator() {
// TODO Not yet implemented
throw new UnsupportedOperationException();
}
public ListIterator<Object> listIterator(int index) {
// TODO Not yet implemented
throw new UnsupportedOperationException();
}
public Iterator<Object> endingIterator() {
return new JustInTimeFilteringEntityIterator(childEntitySelector.endingIterator());
}
private boolean accept(ScoreDirector scoreDirector, Object entity) {
for (SelectionFilter filter : filterList) {
if (!filter.accept(scoreDirector, entity)) {
return false;
}
}
return true;
}
@Override
public String toString() {
return "Filtering(" + childEntitySelector + ")";
}
}
<solver>
<scanAnnotatedClasses>
<packageInclude>com.fast.planner.solution</packageInclude>
</scanAnnotatedClasses>
<scoreDirectorFactory>
<scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
<scoreDrl>com/fast/planner/solution/rostering-rules.drl</scoreDrl>
<initializingScoreTrend>ONLY_DOWN/ONLY_DOWN</initializingScoreTrend>
</scoreDirectorFactory>
<localSearch>
<unionMoveSelector>
<cacheType>PHASE</cacheType>
<selectionOrder>SHUFFLED</selectionOrder>
<changeMoveSelector>
<cacheType>PHASE</cacheType>
<filterClass>com.fast.planner.solution.filter.ReserveRestrictionsChangeMoveFilter</filterClass>
<fixedProbabilityWeight>1.0</fixedProbabilityWeight>
</changeMoveSelector>
<swapMoveSelector>
<cacheType>PHASE</cacheType>
<fixedProbabilityWeight>2.0</fixedProbabilityWeight>
</swapMoveSelector>
</unionMoveSelector>
<acceptor>
<simulatedAnnealingStartingTemperature>2hard/200soft</simulatedAnnealingStartingTemperature>
<entityTabuSize>5</entityTabuSize>
</acceptor>
<forager>
<acceptedCountLimit>4</acceptedCountLimit>
</forager>
</localSearch>
答案 0 :(得分:0)
这是一个错误,将在以后的版本中解决。