From a6a671d48467ab767fe4a19d3729d497e1b33766 Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Mon, 1 Jul 2013 02:48:25 +0200 Subject: [PATCH] enhance jsprit with prematureAlgorithmBreaker, add VariationCoefficientBreaker, TimeBreaker and IterationBreaker --- .../algorithms/VehicleRoutingAlgorithms.java | 56 ++++++++++++++++++- .../IterationWithoutImprovementBreaker.java | 10 ++++ .../main/java/basics/algo/TimeBreaker.java | 45 +++++++++++++++ .../algo/VariationCoefficientBreaker.java | 6 ++ .../src/main/resources/algorithm_schema.xsd | 38 +++++++++++++ 5 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 jsprit-core/src/main/java/basics/algo/TimeBreaker.java diff --git a/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java index 767adc44..71631a38 100644 --- a/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java +++ b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java @@ -56,10 +56,15 @@ import basics.VehicleRoutingProblem.FleetSize; import basics.VehicleRoutingProblemSolution; import basics.algo.AlgorithmStartsListener; import basics.algo.InsertionListener; +import basics.algo.IterationWithoutImprovementBreaker; +import basics.algo.PrematureAlgorithmBreaker; import basics.algo.SearchStrategy; import basics.algo.SearchStrategyManager; import basics.algo.SearchStrategyModule; 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.Priority; import basics.io.AlgorithmConfig; @@ -470,13 +475,62 @@ public class VehicleRoutingAlgorithms { } VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager); 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); registerInsertionListeners(definedClasses,insertionListeners); return metaAlgorithm; } + private static PrematureAlgorithmBreaker getPrematureBreaker(XMLConfiguration config, Set 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 insertionListeners) { for(AbstractKey key : definedClasses.keySet()){ if(key instanceof AbstractInsertionKey){ diff --git a/jsprit-core/src/main/java/basics/algo/IterationWithoutImprovementBreaker.java b/jsprit-core/src/main/java/basics/algo/IterationWithoutImprovementBreaker.java index 0e8dc725..cdcfc7e4 100644 --- a/jsprit-core/src/main/java/basics/algo/IterationWithoutImprovementBreaker.java +++ b/jsprit-core/src/main/java/basics/algo/IterationWithoutImprovementBreaker.java @@ -1,15 +1,25 @@ package basics.algo; +import org.apache.log4j.Logger; + import basics.algo.SearchStrategy.DiscoveredSolution; public class IterationWithoutImprovementBreaker implements PrematureAlgorithmBreaker{ + private static Logger log = Logger.getLogger(IterationWithoutImprovementBreaker.class); + private int nuOfIterationWithoutImprovement; private int iterationsWithoutImprovement = 0; public IterationWithoutImprovementBreaker(int nuOfIterationsWithoutImprovement){ this.nuOfIterationWithoutImprovement=nuOfIterationsWithoutImprovement; + log.info("initialise " + this); + } + + @Override + public String toString() { + return "[name=IterationWithoutImprovementBreaker][iterationsWithoutImprovement="+nuOfIterationWithoutImprovement+"]"; } @Override diff --git a/jsprit-core/src/main/java/basics/algo/TimeBreaker.java b/jsprit-core/src/main/java/basics/algo/TimeBreaker.java new file mode 100644 index 00000000..ac7f4be1 --- /dev/null +++ b/jsprit-core/src/main/java/basics/algo/TimeBreaker.java @@ -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 solutions) { + startTime = System.currentTimeMillis(); + } + +} diff --git a/jsprit-core/src/main/java/basics/algo/VariationCoefficientBreaker.java b/jsprit-core/src/main/java/basics/algo/VariationCoefficientBreaker.java index 1538dd76..2629b5cf 100644 --- a/jsprit-core/src/main/java/basics/algo/VariationCoefficientBreaker.java +++ b/jsprit-core/src/main/java/basics/algo/VariationCoefficientBreaker.java @@ -31,6 +31,12 @@ public class VariationCoefficientBreaker implements PrematureAlgorithmBreaker, A this.nuOfIterations = nuOfIterations; this.variationCoefficientThreshold = variationCoefficientThreshold; solutionValues = new double[nuOfIterations]; + logger.info("initialise " + this); + } + + @Override + public String toString() { + return "[name=VariationCoefficientBreaker][variationCoefficientThreshold="+variationCoefficientThreshold+"][iterations="+nuOfIterations+"]"; } @Override diff --git a/jsprit-core/src/main/resources/algorithm_schema.xsd b/jsprit-core/src/main/resources/algorithm_schema.xsd index 348b07a7..f3992790 100644 --- a/jsprit-core/src/main/resources/algorithm_schema.xsd +++ b/jsprit-core/src/main/resources/algorithm_schema.xsd @@ -27,6 +27,8 @@ + + @@ -104,6 +106,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +