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

add multiple termination criteria

This commit is contained in:
oblonski 2014-09-15 08:26:12 +02:00
parent c75d3d5cc2
commit 4d8b4a6273
5 changed files with 100 additions and 22 deletions

View file

@ -97,15 +97,6 @@ public class VehicleRoutingAlgorithm {
private int maxIterations = 100;
private PrematureAlgorithmTermination prematureAlgorithmTermination = new PrematureAlgorithmTermination() {
@Override
public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) {
return false;
}
};
private TerminationManager terminationManager = new TerminationManager();
private VehicleRoutingProblemSolution bestEver = null;
@ -158,7 +149,8 @@ public class VehicleRoutingAlgorithm {
}
/**
* Sets premature termination.
* Sets premature termination and overrides existing termination criteria. If existing ones should not be
* overridden use <code>.addTerminationCriterion(...)</code>.
*
* @param prematureAlgorithmTermination the termination criterion
*/
@ -168,6 +160,12 @@ public class VehicleRoutingAlgorithm {
// this.prematureAlgorithmTermination = prematureAlgorithmTermination;
}
/**
* Adds a termination criterion to the collection of already specified termination criteria. If one
* of the termination criteria is fulfilled, the algorithm terminates prematurely.
*
* @param terminationCriterion the termination criterion
*/
public void addTerminationCriterion(PrematureAlgorithmTermination terminationCriterion){
terminationManager.addTermination(terminationCriterion);
}

View file

@ -18,7 +18,6 @@ package jsprit.core.algorithm.io;
import jsprit.core.algorithm.*;
import jsprit.core.algorithm.SearchStrategy.DiscoveredSolution;
import jsprit.core.algorithm.acceptor.*;
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms.TypedMap.*;
import jsprit.core.algorithm.listener.AlgorithmEndsListener;
@ -606,8 +605,16 @@ public class VehicleRoutingAlgorithms {
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new VehicleSwitched(vehicleFleetManager));
//define prematureBreak
PrematureAlgorithmTermination prematureAlgoBreaker = getPrematureBreaker(config,algorithmListeners);
metaAlgorithm.setPrematureAlgorithmTermination(prematureAlgoBreaker);
PrematureAlgorithmTermination prematureAlgorithmTermination = getPrematureTermination(config, algorithmListeners);
if(prematureAlgorithmTermination != null) metaAlgorithm.setPrematureAlgorithmTermination(prematureAlgorithmTermination);
else{
List<HierarchicalConfiguration> terminationCriteria = config.configurationsAt("terminationCriteria.termination");
for(HierarchicalConfiguration terminationConfig : terminationCriteria){
PrematureAlgorithmTermination termination = getTerminationCriterion(terminationConfig, algorithmListeners);
if(termination != null) metaAlgorithm.addTerminationCriterion(termination);
}
}
//misc
// algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier()));
@ -634,17 +641,48 @@ public class VehicleRoutingAlgorithms {
"makes sure your config file contains one of these options");
}
private static PrematureAlgorithmTermination getPrematureBreaker(XMLConfiguration config, Set<PrioritizedVRAListener> algorithmListeners) {
private static PrematureAlgorithmTermination getTerminationCriterion(HierarchicalConfiguration config, Set<PrioritizedVRAListener> algorithmListeners) {
String basedOn = config.getString("[@basedOn]");
if(basedOn == null){
log.info("set default prematureBreak, i.e. no premature break at all.");
return null;
}
if(basedOn.equals("iterations")){
log.info("set prematureBreak based on iterations");
String iter = config.getString("iterations");
if(iter == null) throw new IllegalStateException("iterations is missing");
int iterations = Integer.valueOf(iter);
return new IterationWithoutImprovementTermination(iterations);
}
if(basedOn.equals("time")){
log.info("set prematureBreak based on time");
String timeString = config.getString("time");
if(timeString == null) throw new IllegalStateException("time is missing");
double time = Double.valueOf(timeString);
TimeTermination timeBreaker = new TimeTermination(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("threshold");
String iterationsString = config.getString("iterations");
if(thresholdString == null) throw new IllegalStateException("threshold is missing");
if(iterationsString == null) throw new IllegalStateException("iterations is missing");
double threshold = Double.valueOf(thresholdString);
int iterations = Integer.valueOf(iterationsString);
VariationCoefficientTermination variationCoefficientBreaker = new VariationCoefficientTermination(iterations, threshold);
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, variationCoefficientBreaker));
return variationCoefficientBreaker;
}
throw new IllegalStateException("prematureBreak basedOn " + basedOn + " is not defined");
}
private static PrematureAlgorithmTermination getPrematureTermination(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 PrematureAlgorithmTermination() {
@Override
public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) {
return false;
}
};
return null;
}
if(basedOn.equals("iterations")){
log.info("set prematureBreak based on iterations");

View file

@ -143,4 +143,43 @@ public class VehicleRoutingAlgorithmTest {
assertEquals(50,counter.getCountIterations());
}
@Test
public void whenAddingPrematureTwoTerminationCriteria_itIsExecutedCorrectly(){
SearchStrategyManager stratManager = mock(SearchStrategyManager.class);
VehicleRoutingAlgorithm algorithm = new VehicleRoutingAlgorithm(mock(VehicleRoutingProblem.class),stratManager);
when(stratManager.getRandomStrategy()).thenReturn(mock(SearchStrategy.class));
when(stratManager.getProbabilities()).thenReturn(Arrays.asList(1.0));
algorithm.setMaxIterations(1000);
PrematureAlgorithmTermination termination = new PrematureAlgorithmTermination() {
private int nuOfIterations = 1;
@Override
public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) {
if(nuOfIterations == 50) return true;
nuOfIterations++;
return false;
}
};
PrematureAlgorithmTermination termination2 = new PrematureAlgorithmTermination() {
private int nuOfIterations = 1;
@Override
public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) {
if(nuOfIterations == 25) return true;
nuOfIterations++;
return false;
}
};
CountIterations counter = new CountIterations();
algorithm.addListener(counter);
algorithm.addTerminationCriterion(termination);
algorithm.addTerminationCriterion(termination2);
algorithm.searchSolutions();
assertEquals(25,counter.getCountIterations());
}
}

View file

@ -99,7 +99,7 @@ public class TestAlgorithmReader {
IterationCounter iCounter = new IterationCounter();
vra.addListener(iCounter);
vra.searchSolutions();
Assert.assertEquals(100,iCounter.iterations);
Assert.assertEquals(25,iCounter.iterations);
}

View file

@ -25,6 +25,9 @@
<termination basedOn="iterations">
<iterations>100</iterations>
</termination>
<termination basedOn="iterations">
<iterations>25</iterations>
</termination>
</terminationCriteria>
<construction>