1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

enhance jsprit with prematureAlgorithmBreaker, add

VariationCoefficientBreaker, TimeBreaker and IterationBreaker
This commit is contained in:
oblonski 2013-07-01 02:48:25 +02:00
parent 6b7c1f035b
commit a6a671d484
5 changed files with 154 additions and 1 deletions

View file

@ -56,10 +56,15 @@ import basics.VehicleRoutingProblem.FleetSize;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.algo.AlgorithmStartsListener; import basics.algo.AlgorithmStartsListener;
import basics.algo.InsertionListener; import basics.algo.InsertionListener;
import basics.algo.IterationWithoutImprovementBreaker;
import basics.algo.PrematureAlgorithmBreaker;
import basics.algo.SearchStrategy; import basics.algo.SearchStrategy;
import basics.algo.SearchStrategyManager; import basics.algo.SearchStrategyManager;
import basics.algo.SearchStrategyModule; import basics.algo.SearchStrategyModule;
import basics.algo.SearchStrategyModuleListener; import basics.algo.SearchStrategyModuleListener;
import basics.algo.TimeBreaker;
import basics.algo.VariationCoefficientBreaker;
import basics.algo.SearchStrategy.DiscoveredSolution;
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener; import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
import basics.algo.VehicleRoutingAlgorithmListeners.Priority; import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
import basics.io.AlgorithmConfig; import basics.io.AlgorithmConfig;
@ -470,13 +475,62 @@ public class VehicleRoutingAlgorithms {
} }
VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager); VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager);
if(config.containsKey("iterations")){ if(config.containsKey("iterations")){
metaAlgorithm.setNuOfIterations(config.getInt("iterations")); int iter = config.getInt("iterations");
metaAlgorithm.setNuOfIterations(iter);
log.info("set nuOfIterations to " + iter);
} }
//prematureBreak
PrematureAlgorithmBreaker prematureAlgoBreaker = getPrematureBreaker(config,algorithmListeners);
metaAlgorithm.setPrematureAlgorithmBreaker(prematureAlgoBreaker);
registerListeners(metaAlgorithm,algorithmListeners); registerListeners(metaAlgorithm,algorithmListeners);
registerInsertionListeners(definedClasses,insertionListeners); registerInsertionListeners(definedClasses,insertionListeners);
return metaAlgorithm; return metaAlgorithm;
} }
private static PrematureAlgorithmBreaker getPrematureBreaker(XMLConfiguration config, Set<PrioritizedVRAListener> algorithmListeners) {
String basedOn = config.getString("prematureBreak[@basedOn]");
if(basedOn == null){
log.info("set default prematureBreak, i.e. no premature break at all.");
return new PrematureAlgorithmBreaker() {
@Override
public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) {
return false;
}
};
}
if(basedOn.equals("iterations")){
log.info("set prematureBreak based on iterations");
String iter = config.getString("prematureBreak.iterations");
if(iter == null) throw new IllegalStateException("prematureBreak.iterations is missing");
int iterations = Integer.valueOf(iter);
return new IterationWithoutImprovementBreaker(iterations);
}
if(basedOn.equals("time")){
log.info("set prematureBreak based on time");
String timeString = config.getString("prematureBreak.time");
if(timeString == null) throw new IllegalStateException("prematureBreak.time is missing");
double time = Double.valueOf(timeString);
TimeBreaker timeBreaker = new TimeBreaker(time);
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, timeBreaker));
return timeBreaker;
}
if(basedOn.equals("variationCoefficient")){
log.info("set prematureBreak based on variation coefficient");
String thresholdString = config.getString("prematureBreak.threshold");
String iterationsString = config.getString("prematureBreak.iterations");
if(thresholdString == null) throw new IllegalStateException("prematureBreak.threshold is missing");
if(iterationsString == null) throw new IllegalStateException("prematureBreak.iterations is missing");
double threshold = Double.valueOf(thresholdString);
int iterations = Integer.valueOf(iterationsString);
VariationCoefficientBreaker variationCoefficientBreaker = new VariationCoefficientBreaker(iterations, threshold);
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, variationCoefficientBreaker));
return variationCoefficientBreaker;
}
throw new IllegalStateException("prematureBreak basedOn " + basedOn + " is not defined");
}
private static void registerInsertionListeners(TypedMap definedClasses, List<InsertionListener> insertionListeners) { private static void registerInsertionListeners(TypedMap definedClasses, List<InsertionListener> insertionListeners) {
for(AbstractKey<?> key : definedClasses.keySet()){ for(AbstractKey<?> key : definedClasses.keySet()){
if(key instanceof AbstractInsertionKey){ if(key instanceof AbstractInsertionKey){

View file

@ -1,15 +1,25 @@
package basics.algo; package basics.algo;
import org.apache.log4j.Logger;
import basics.algo.SearchStrategy.DiscoveredSolution; import basics.algo.SearchStrategy.DiscoveredSolution;
public class IterationWithoutImprovementBreaker implements PrematureAlgorithmBreaker{ public class IterationWithoutImprovementBreaker implements PrematureAlgorithmBreaker{
private static Logger log = Logger.getLogger(IterationWithoutImprovementBreaker.class);
private int nuOfIterationWithoutImprovement; private int nuOfIterationWithoutImprovement;
private int iterationsWithoutImprovement = 0; private int iterationsWithoutImprovement = 0;
public IterationWithoutImprovementBreaker(int nuOfIterationsWithoutImprovement){ public IterationWithoutImprovementBreaker(int nuOfIterationsWithoutImprovement){
this.nuOfIterationWithoutImprovement=nuOfIterationsWithoutImprovement; this.nuOfIterationWithoutImprovement=nuOfIterationsWithoutImprovement;
log.info("initialise " + this);
}
@Override
public String toString() {
return "[name=IterationWithoutImprovementBreaker][iterationsWithoutImprovement="+nuOfIterationWithoutImprovement+"]";
} }
@Override @Override

View file

@ -0,0 +1,45 @@
package basics.algo;
import java.util.Collection;
import org.apache.commons.math.stat.StatUtils;
import org.apache.commons.math.stat.descriptive.moment.Mean;
import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;
import org.apache.log4j.Logger;
import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution;
import basics.algo.SearchStrategy.DiscoveredSolution;
public class TimeBreaker implements PrematureAlgorithmBreaker, AlgorithmStartsListener{
private static Logger logger = Logger.getLogger(TimeBreaker.class);
private double timeThreshold;
private double startTime;
public TimeBreaker(double time) {
super();
this.timeThreshold = time;
logger.info("initialise " + this);
}
@Override
public String toString() {
return "[name=TimeBreaker][timeThreshold="+timeThreshold+"]";
}
@Override
public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) {
if((System.currentTimeMillis() - startTime)/1000.0 > timeThreshold) return true;
return false;
}
@Override
public void informAlgorithmStarts(VehicleRoutingProblem problem,VehicleRoutingAlgorithm algorithm,Collection<VehicleRoutingProblemSolution> solutions) {
startTime = System.currentTimeMillis();
}
}

View file

@ -31,6 +31,12 @@ public class VariationCoefficientBreaker implements PrematureAlgorithmBreaker, A
this.nuOfIterations = nuOfIterations; this.nuOfIterations = nuOfIterations;
this.variationCoefficientThreshold = variationCoefficientThreshold; this.variationCoefficientThreshold = variationCoefficientThreshold;
solutionValues = new double[nuOfIterations]; solutionValues = new double[nuOfIterations];
logger.info("initialise " + this);
}
@Override
public String toString() {
return "[name=VariationCoefficientBreaker][variationCoefficientThreshold="+variationCoefficientThreshold+"][iterations="+nuOfIterations+"]";
} }
@Override @Override

View file

@ -27,6 +27,8 @@
<xs:sequence> <xs:sequence>
<xs:element name="iterations" type="xs:integer" minOccurs="0" maxOccurs="1" default="100"/> <xs:element name="iterations" type="xs:integer" minOccurs="0" maxOccurs="1" default="100"/>
<xs:element name="prematureBreak" type="prematureBreakType" minOccurs="0" maxOccurs="1"/>
<xs:element name="construction" minOccurs="0" maxOccurs="1"> <xs:element name="construction" minOccurs="0" maxOccurs="1">
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
@ -104,6 +106,42 @@
</xs:complexType> </xs:complexType>
<xs:complexType name="prematureBreakType">
<xs:choice>
<xs:group ref="pBreak_iteration_group"/>
<xs:group ref="pBreak_time_group"/>
<xs:group ref="pBreak_variationCoefficient_group"/>
</xs:choice>
<xs:attribute name="basedOn">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="time"/>
<xs:enumeration value="iterations"/>
<xs:enumeration value="variationCoefficient"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
<xs:group name="pBreak_iteration_group">
<xs:sequence>
<xs:element name="iterations" type="xs:integer" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:group>
<xs:group name="pBreak_time_group">
<xs:sequence>
<xs:element name="time" type="xs:double" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:group>
<xs:group name="pBreak_variationCoefficient_group">
<xs:sequence>
<xs:element name="threshold" type="xs:double" minOccurs="1" maxOccurs="1"/>
<xs:element name="iterations" type="xs:integer" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:group>
<xs:complexType name="moduleType"> <xs:complexType name="moduleType">
<xs:choice> <xs:choice>
<xs:group ref="ruin_and_recreate_group"/> <xs:group ref="ruin_and_recreate_group"/>