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:
parent
c75d3d5cc2
commit
4d8b4a6273
5 changed files with 100 additions and 22 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@
|
|||
<termination basedOn="iterations">
|
||||
<iterations>100</iterations>
|
||||
</termination>
|
||||
<termination basedOn="iterations">
|
||||
<iterations>25</iterations>
|
||||
</termination>
|
||||
</terminationCriteria>
|
||||
|
||||
<construction>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue