/**
* 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.config.localsearch.decider.acceptor;
import java.util.ArrayList;
import java.util.List;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import org.apache.commons.lang.ObjectUtils;
import org.drools.planner.core.localsearch.decider.acceptor.Acceptor;
import org.drools.planner.core.localsearch.decider.acceptor.CompositeAcceptor;
import org.drools.planner.core.localsearch.decider.acceptor.greatdeluge.GreatDelugeAcceptor;
import org.drools.planner.core.localsearch.decider.acceptor.simulatedannealing.LegacySimulatedAnnealingAcceptor;
import org.drools.planner.core.localsearch.decider.acceptor.simulatedannealing.SimulatedAnnealingAcceptor;
import org.drools.planner.core.localsearch.decider.acceptor.tabu.MoveTabuAcceptor;
import org.drools.planner.core.localsearch.decider.acceptor.tabu.PropertyTabuAcceptor;
import org.drools.planner.core.localsearch.decider.acceptor.tabu.SolutionTabuAcceptor;
/**
* @author Geoffrey De Smet
*/
@XStreamAlias("acceptor")
public class AcceptorConfig {
private Acceptor acceptor = null; // TODO make into a list
private Class<Acceptor> acceptorClass = null;
@XStreamImplicit(itemFieldName = "acceptorType")
private List<AcceptorType> acceptorTypeList = null;
protected Integer completeMoveTabuSize = null;
protected Integer partialMoveTabuSize = null;
protected Integer completeUndoMoveTabuSize = null;
protected Integer partialUndoMoveTabuSize = null;
protected Integer completePropertyTabuSize = null;
protected Integer partialPropertyTabuSize = null;
protected Integer completeSolutionTabuSize = null;
protected Integer partialSolutionTabuSize = null;
protected Double simulatedAnnealingStartingTemperature = null;
protected Double simulatedAnnealingTemperatureSurvival = null;
protected Double greatDelugeWaterLevelUpperBoundRate = null;
protected Double greatDelugeWaterRisingRate = null;
public Acceptor getAcceptor() {
return acceptor;
}
public void setAcceptor(Acceptor acceptor) {
this.acceptor = acceptor;
}
public Class<Acceptor> getAcceptorClass() {
return acceptorClass;
}
public void setAcceptorClass(Class<Acceptor> acceptorClass) {
this.acceptorClass = acceptorClass;
}
public List<AcceptorType> getAcceptorTypeList() {
return acceptorTypeList;
}
public void setAcceptorTypeList(List<AcceptorType> acceptorTypeList) {
this.acceptorTypeList = acceptorTypeList;
}
public Integer getCompleteMoveTabuSize() {
return completeMoveTabuSize;
}
public void setCompleteMoveTabuSize(Integer completeMoveTabuSize) {
this.completeMoveTabuSize = completeMoveTabuSize;
}
public Integer getPartialMoveTabuSize() {
return partialMoveTabuSize;
}
public void setPartialMoveTabuSize(Integer partialMoveTabuSize) {
this.partialMoveTabuSize = partialMoveTabuSize;
}
public Integer getCompleteUndoMoveTabuSize() {
return completeUndoMoveTabuSize;
}
public void setCompleteUndoMoveTabuSize(Integer completeUndoMoveTabuSize) {
this.completeUndoMoveTabuSize = completeUndoMoveTabuSize;
}
public Integer getPartialUndoMoveTabuSize() {
return partialUndoMoveTabuSize;
}
public void setPartialUndoMoveTabuSize(Integer partialUndoMoveTabuSize) {
this.partialUndoMoveTabuSize = partialUndoMoveTabuSize;
}
public Integer getCompletePropertyTabuSize() {
return completePropertyTabuSize;
}
public void setCompletePropertyTabuSize(Integer completePropertyTabuSize) {
this.completePropertyTabuSize = completePropertyTabuSize;
}
public Integer getPartialPropertyTabuSize() {
return partialPropertyTabuSize;
}
public void setPartialPropertyTabuSize(Integer partialPropertyTabuSize) {
this.partialPropertyTabuSize = partialPropertyTabuSize;
}
public Integer getCompleteSolutionTabuSize() {
return completeSolutionTabuSize;
}
public void setCompleteSolutionTabuSize(Integer completeSolutionTabuSize) {
this.completeSolutionTabuSize = completeSolutionTabuSize;
}
public Integer getPartialSolutionTabuSize() {
return partialSolutionTabuSize;
}
public void setPartialSolutionTabuSize(Integer partialSolutionTabuSize) {
this.partialSolutionTabuSize = partialSolutionTabuSize;
}
public Double getSimulatedAnnealingStartingTemperature() {
return simulatedAnnealingStartingTemperature;
}
public void setSimulatedAnnealingStartingTemperature(Double simulatedAnnealingStartingTemperature) {
this.simulatedAnnealingStartingTemperature = simulatedAnnealingStartingTemperature;
}
public Double getGreatDelugeWaterLevelUpperBoundRate() {
return greatDelugeWaterLevelUpperBoundRate;
}
public void setGreatDelugeWaterLevelUpperBoundRate(Double greatDelugeWaterLevelUpperBoundRate) {
this.greatDelugeWaterLevelUpperBoundRate = greatDelugeWaterLevelUpperBoundRate;
}
public Double getGreatDelugeWaterRisingRate() {
return greatDelugeWaterRisingRate;
}
public void setGreatDelugeWaterRisingRate(Double greatDelugeWaterRisingRate) {
this.greatDelugeWaterRisingRate = greatDelugeWaterRisingRate;
}
// ************************************************************************
// Builder methods
// ************************************************************************
public Acceptor buildAcceptor() {
List<Acceptor> acceptorList = new ArrayList<Acceptor>();
if (acceptor != null) {
acceptorList.add(acceptor);
}
if (acceptorClass != null) {
try {
acceptorList.add(acceptorClass.newInstance());
} catch (InstantiationException e) {
throw new IllegalArgumentException("acceptorClass (" + acceptorClass.getName()
+ ") does not have a public no-arg constructor", e);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("acceptorClass (" + acceptorClass.getName()
+ ") does not have a public no-arg constructor", e);
}
}
if ((acceptorTypeList != null && acceptorTypeList.contains(AcceptorType.MOVE_TABU))
|| completeMoveTabuSize != null || partialMoveTabuSize != null) {
MoveTabuAcceptor moveTabuAcceptor = new MoveTabuAcceptor();
moveTabuAcceptor.setUseUndoMoveAsTabuMove(false);
if (completeMoveTabuSize != null) {
moveTabuAcceptor.setCompleteTabuSize(completeMoveTabuSize);
}
if (partialMoveTabuSize != null) {
moveTabuAcceptor.setPartialTabuSize(partialMoveTabuSize);
}
acceptorList.add(moveTabuAcceptor);
}
if ((acceptorTypeList != null && acceptorTypeList.contains(AcceptorType.UNDO_MOVE_TABU))
|| completeUndoMoveTabuSize != null || partialUndoMoveTabuSize != null) {
MoveTabuAcceptor undoMoveTabuAcceptor = new MoveTabuAcceptor();
undoMoveTabuAcceptor.setUseUndoMoveAsTabuMove(true);
if (completeUndoMoveTabuSize != null) {
undoMoveTabuAcceptor.setCompleteTabuSize(completeUndoMoveTabuSize);
}
if (partialUndoMoveTabuSize != null) {
undoMoveTabuAcceptor.setPartialTabuSize(partialUndoMoveTabuSize);
}
acceptorList.add(undoMoveTabuAcceptor);
}
if ((acceptorTypeList != null && acceptorTypeList.contains(AcceptorType.PROPERTY_TABU))
|| completePropertyTabuSize != null || partialPropertyTabuSize != null) {
PropertyTabuAcceptor propertyTabuAcceptor = new PropertyTabuAcceptor();
if (completePropertyTabuSize != null) {
propertyTabuAcceptor.setCompleteTabuSize(completePropertyTabuSize);
}
if (partialPropertyTabuSize != null) {
propertyTabuAcceptor.setPartialTabuSize(partialPropertyTabuSize);
}
acceptorList.add(propertyTabuAcceptor);
}
if ((acceptorTypeList != null && acceptorTypeList.contains(AcceptorType.SOLUTION_TABU))
|| completeSolutionTabuSize != null || partialSolutionTabuSize != null) {
SolutionTabuAcceptor solutionTabuAcceptor = new SolutionTabuAcceptor();
if (completeSolutionTabuSize != null) {
solutionTabuAcceptor.setCompleteTabuSize(completeSolutionTabuSize);
}
if (partialSolutionTabuSize != null) {
solutionTabuAcceptor.setPartialTabuSize(partialSolutionTabuSize);
}
acceptorList.add(solutionTabuAcceptor);
}
if ((acceptorTypeList != null && acceptorTypeList.contains(AcceptorType.SIMULATED_ANNEALING))
|| simulatedAnnealingStartingTemperature != null) {
SimulatedAnnealingAcceptor simulatedAnnealingAcceptor = new SimulatedAnnealingAcceptor();
if (simulatedAnnealingStartingTemperature != null) {
simulatedAnnealingAcceptor.setStartingTemperature(simulatedAnnealingStartingTemperature);
}
acceptorList.add(simulatedAnnealingAcceptor);
}
if ((acceptorTypeList != null && acceptorTypeList.contains(AcceptorType.GREAT_DELUGE))
|| greatDelugeWaterLevelUpperBoundRate != null || greatDelugeWaterRisingRate != null) {
double waterLevelUpperBoundRate = (Double) ObjectUtils.defaultIfNull(
greatDelugeWaterLevelUpperBoundRate, 1.20);
double waterRisingRate = (Double) ObjectUtils.defaultIfNull(
greatDelugeWaterRisingRate, 0.0000001);
acceptorList.add(new GreatDelugeAcceptor(waterLevelUpperBoundRate, waterRisingRate));
}
if ((acceptorTypeList != null && acceptorTypeList.contains(AcceptorType.LATE_ACCEPTANCE))) {
// TODO implement LATE_ACCEPTANCE
throw new UnsupportedOperationException("LATE_ACCEPTANCE not yet supported.");
}
if (acceptorList.size() == 1) {
return acceptorList.get(0);
} else if (acceptorList.size() > 1) {
CompositeAcceptor compositeAcceptor = new CompositeAcceptor();
compositeAcceptor.setAcceptorList(acceptorList);
return compositeAcceptor;
} else {
SolutionTabuAcceptor solutionTabuAcceptor = new SolutionTabuAcceptor();
solutionTabuAcceptor.setCompleteTabuSize(1500); // TODO number pulled out of thin air
return solutionTabuAcceptor;
}
}
public void inherit(AcceptorConfig inheritedConfig) {
// inherited acceptors get compositely added
if (acceptor == null) {
acceptor = inheritedConfig.getAcceptor();
}
if (acceptorClass == null) {
acceptorClass = inheritedConfig.getAcceptorClass();
}
if (acceptorTypeList == null) {
acceptorTypeList = inheritedConfig.getAcceptorTypeList();
} else {
List<AcceptorType> inheritedAcceptorTypeList = inheritedConfig.getAcceptorTypeList();
if (inheritedAcceptorTypeList != null) {
for (AcceptorType acceptorType : inheritedAcceptorTypeList) {
if (!acceptorTypeList.contains(acceptorType)) {
acceptorTypeList.add(acceptorType);
}
}
}
}
if (completeMoveTabuSize == null) {
completeMoveTabuSize = inheritedConfig.getCompleteMoveTabuSize();
}
if (partialMoveTabuSize == null) {
partialMoveTabuSize = inheritedConfig.getPartialMoveTabuSize();
}
if (completeUndoMoveTabuSize == null) {
completeUndoMoveTabuSize = inheritedConfig.getCompleteUndoMoveTabuSize();
}
if (partialUndoMoveTabuSize == null) {
partialUndoMoveTabuSize = inheritedConfig.getPartialUndoMoveTabuSize();
}
if (completePropertyTabuSize == null) {
completePropertyTabuSize = inheritedConfig.getCompletePropertyTabuSize();
}
if (partialPropertyTabuSize == null) {
partialPropertyTabuSize = inheritedConfig.getPartialPropertyTabuSize();
}
if (completeSolutionTabuSize == null) {
completeSolutionTabuSize = inheritedConfig.getCompleteSolutionTabuSize();
}
if (partialSolutionTabuSize == null) {
partialSolutionTabuSize = inheritedConfig.getPartialSolutionTabuSize();
}
if (simulatedAnnealingStartingTemperature == null) {
simulatedAnnealingStartingTemperature = inheritedConfig.getSimulatedAnnealingStartingTemperature();
}
if (greatDelugeWaterLevelUpperBoundRate == null) {
greatDelugeWaterLevelUpperBoundRate = inheritedConfig.getGreatDelugeWaterLevelUpperBoundRate();
}
if (greatDelugeWaterRisingRate == null) {
greatDelugeWaterRisingRate = inheritedConfig.getGreatDelugeWaterRisingRate();
}
}
public static enum AcceptorType {
MOVE_TABU,
UNDO_MOVE_TABU,
PROPERTY_TABU,
SOLUTION_TABU,
SIMULATED_ANNEALING,
LATE_ACCEPTANCE,
GREAT_DELUGE,
}
}