/** * Copyright 2010 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.planner.core.localsearch.decider.selector; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Random; import org.drools.planner.core.localsearch.LocalSearchSolverScope; import org.drools.planner.core.localsearch.StepScope; import org.drools.planner.core.localsearch.decider.Decider; import org.drools.planner.core.move.Move; /** * A CompositeSelector unions multiple Selectors. * @author Geoffrey De Smet */ public class CompositeSelector extends AbstractSelector { protected List<Selector> selectorList; public void setSelectorList(List<Selector> selectorList) { this.selectorList = selectorList; } @Override public void setDecider(Decider decider) { super.setDecider(decider); for (Selector selector : selectorList) { selector.setDecider(decider); } } // ************************************************************************ // Worker methods // ************************************************************************ @Override public void solvingStarted(LocalSearchSolverScope localSearchSolverScope) { for (Selector selector : selectorList) { selector.solvingStarted(localSearchSolverScope); } } @Override public void beforeDeciding(StepScope stepScope) { for (Selector selector : selectorList) { selector.beforeDeciding(stepScope); } } public Iterator<Move> moveIterator(StepScope stepScope) { List<Iterator<Move>> moveIteratorList = new ArrayList<Iterator<Move>>(selectorList.size()); for (Selector selector : selectorList) { Iterator<Move> moveIterator = selector.moveIterator(stepScope); if (moveIterator.hasNext()) { moveIteratorList.add(moveIterator); } } return new CompositeSelectorMoveIterator(stepScope.getWorkingRandom(), moveIteratorList); } @Override public void stepDecided(StepScope stepScope) { for (Selector selector : selectorList) { selector.stepDecided(stepScope); } } @Override public void stepTaken(StepScope stepScope) { for (Selector selector : selectorList) { selector.stepTaken(stepScope); } } @Override public void solvingEnded(LocalSearchSolverScope localSearchSolverScope) { for (Selector selector : selectorList) { selector.solvingEnded(localSearchSolverScope); } } private static class CompositeSelectorMoveIterator implements Iterator<Move> { private final List<Iterator<Move>> moveIteratorList; private final Random workingRandom; public CompositeSelectorMoveIterator(Random workingRandom, List<Iterator<Move>> moveIteratorList) { this.moveIteratorList = moveIteratorList; this.workingRandom = workingRandom; } public boolean hasNext() { return !moveIteratorList.isEmpty(); } public Move next() { int moveIteratorIndex = workingRandom.nextInt(moveIteratorList.size()); Iterator<Move> moveIterator = moveIteratorList.get(moveIteratorIndex); Move next = moveIterator.next(); if (!moveIterator.hasNext()) { moveIteratorList.remove(moveIteratorIndex); } return next; } public void remove() { throw new UnsupportedOperationException( "The remove method is not supported on CompositeSelectorMoveIterator"); } } }