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 int maxIterations = 100;
|
||||||
|
|
||||||
private PrematureAlgorithmTermination prematureAlgorithmTermination = new PrematureAlgorithmTermination() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
private TerminationManager terminationManager = new TerminationManager();
|
private TerminationManager terminationManager = new TerminationManager();
|
||||||
|
|
||||||
private VehicleRoutingProblemSolution bestEver = null;
|
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
|
* @param prematureAlgorithmTermination the termination criterion
|
||||||
*/
|
*/
|
||||||
|
|
@ -168,6 +160,12 @@ public class VehicleRoutingAlgorithm {
|
||||||
// this.prematureAlgorithmTermination = prematureAlgorithmTermination;
|
// 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){
|
public void addTerminationCriterion(PrematureAlgorithmTermination terminationCriterion){
|
||||||
terminationManager.addTermination(terminationCriterion);
|
terminationManager.addTermination(terminationCriterion);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ package jsprit.core.algorithm.io;
|
||||||
|
|
||||||
|
|
||||||
import jsprit.core.algorithm.*;
|
import jsprit.core.algorithm.*;
|
||||||
import jsprit.core.algorithm.SearchStrategy.DiscoveredSolution;
|
|
||||||
import jsprit.core.algorithm.acceptor.*;
|
import jsprit.core.algorithm.acceptor.*;
|
||||||
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms.TypedMap.*;
|
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms.TypedMap.*;
|
||||||
import jsprit.core.algorithm.listener.AlgorithmEndsListener;
|
import jsprit.core.algorithm.listener.AlgorithmEndsListener;
|
||||||
|
|
@ -606,8 +605,16 @@ public class VehicleRoutingAlgorithms {
|
||||||
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new VehicleSwitched(vehicleFleetManager));
|
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new VehicleSwitched(vehicleFleetManager));
|
||||||
|
|
||||||
//define prematureBreak
|
//define prematureBreak
|
||||||
PrematureAlgorithmTermination prematureAlgoBreaker = getPrematureBreaker(config,algorithmListeners);
|
PrematureAlgorithmTermination prematureAlgorithmTermination = getPrematureTermination(config, algorithmListeners);
|
||||||
metaAlgorithm.setPrematureAlgorithmTermination(prematureAlgoBreaker);
|
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
|
//misc
|
||||||
// algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier()));
|
// 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");
|
"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]");
|
String basedOn = config.getString("prematureBreak[@basedOn]");
|
||||||
if(basedOn == null){
|
if(basedOn == null){
|
||||||
log.info("set default prematureBreak, i.e. no premature break at all.");
|
log.info("set default prematureBreak, i.e. no premature break at all.");
|
||||||
return new PrematureAlgorithmTermination() {
|
return null;
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
if(basedOn.equals("iterations")){
|
if(basedOn.equals("iterations")){
|
||||||
log.info("set prematureBreak based on iterations");
|
log.info("set prematureBreak based on iterations");
|
||||||
|
|
|
||||||
|
|
@ -143,4 +143,43 @@ public class VehicleRoutingAlgorithmTest {
|
||||||
assertEquals(50,counter.getCountIterations());
|
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();
|
IterationCounter iCounter = new IterationCounter();
|
||||||
vra.addListener(iCounter);
|
vra.addListener(iCounter);
|
||||||
vra.searchSolutions();
|
vra.searchSolutions();
|
||||||
Assert.assertEquals(100,iCounter.iterations);
|
Assert.assertEquals(25,iCounter.iterations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,9 @@
|
||||||
<termination basedOn="iterations">
|
<termination basedOn="iterations">
|
||||||
<iterations>100</iterations>
|
<iterations>100</iterations>
|
||||||
</termination>
|
</termination>
|
||||||
|
<termination basedOn="iterations">
|
||||||
|
<iterations>25</iterations>
|
||||||
|
</termination>
|
||||||
</terminationCriteria>
|
</terminationCriteria>
|
||||||
|
|
||||||
<construction>
|
<construction>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue