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:
parent
6b7c1f035b
commit
a6a671d484
5 changed files with 154 additions and 1 deletions
|
|
@ -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){
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
45
jsprit-core/src/main/java/basics/algo/TimeBreaker.java
Normal file
45
jsprit-core/src/main/java/basics/algo/TimeBreaker.java
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"/>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue