diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java index 5a1eaabe..97475eb6 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithm.java @@ -39,6 +39,25 @@ import java.util.Collection; */ public class VehicleRoutingAlgorithm { + private static class TerminationManager implements PrematureAlgorithmTermination { + + private Collection terminationCriteria = new ArrayList(); + + void addTermination(PrematureAlgorithmTermination termination){ + terminationCriteria.add(termination); + } + + @Override + public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) { + for(PrematureAlgorithmTermination termination : terminationCriteria){ + if(termination.isPrematureBreak(discoveredSolution)){ + return true; + } + } + return false; + } + } + private static class Counter { private final String name; private long counter = 0; @@ -87,6 +106,8 @@ public class VehicleRoutingAlgorithm { }; + private TerminationManager terminationManager = new TerminationManager(); + private VehicleRoutingProblemSolution bestEver = null; public VehicleRoutingAlgorithm(VehicleRoutingProblem problem, SearchStrategyManager searchStrategyManager) { @@ -142,9 +163,15 @@ public class VehicleRoutingAlgorithm { * @param prematureAlgorithmTermination the termination criterion */ public void setPrematureAlgorithmTermination(PrematureAlgorithmTermination prematureAlgorithmTermination){ - this.prematureAlgorithmTermination = prematureAlgorithmTermination; + terminationManager = new TerminationManager(); + terminationManager.addTermination(prematureAlgorithmTermination); +// this.prematureAlgorithmTermination = prematureAlgorithmTermination; } + public void addTerminationCriterion(PrematureAlgorithmTermination terminationCriterion){ + terminationManager.addTermination(terminationCriterion); + } + /** * Gets the {@link SearchStrategyManager}. * @@ -182,7 +209,8 @@ public class VehicleRoutingAlgorithm { DiscoveredSolution discoveredSolution = strategy.run(problem, solutions); memorizeIfBestEver(discoveredSolution); selectedStrategy(strategy.getName(),problem, solutions); - if(prematureAlgorithmTermination.isPrematureBreak(discoveredSolution)){ +// if(prematureAlgorithmTermination.isPrematureBreak(discoveredSolution)){ + if(terminationManager.isPrematureBreak(discoveredSolution)){ logger.info("premature break at iteration "+ (i+1)); noIterationsThisAlgoIsRunning = (i+1); break; diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java index 4ce8fb42..42705a3b 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java @@ -1,16 +1,16 @@ /******************************************************************************* - * Copyright (C) 2013 Stefan Schroeder - * + * Copyright (C) 2014 Stefan Schroeder + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either + * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . ******************************************************************************/ @@ -446,7 +446,7 @@ public class VehicleRoutingAlgorithms { if(firstAct){ firstAct=false; if(!vehicle.isReturnToDepot()){ - assert activity.getLocationId() == end.getLocationId() : "route end and last activity are not equal even route is open. this should not be."; + assert activity.getLocationId().equals(end.getLocationId()) : "route end and last activity are not equal even route is open. this should not be."; } } @@ -594,11 +594,10 @@ public class VehicleRoutingAlgorithms { //construct algorithm VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager); - if(config.containsKey("iterations")){ - int iter = config.getInt("iterations"); - metaAlgorithm.setNuOfIterations(iter); - } - + String maxIterationsString = config.getString("iterations"); + if(maxIterationsString == null) maxIterationsString = config.getString("maxIterations"); + if(maxIterationsString != null) metaAlgorithm.setMaxIterations(Integer.parseInt(maxIterationsString)); + metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager); metaAlgorithm.getAlgorithmListeners().addListener(stateManager); diff --git a/jsprit-core/src/main/resources/algorithm_schema.xsd b/jsprit-core/src/main/resources/algorithm_schema.xsd index a87138e5..ee2fc1f2 100644 --- a/jsprit-core/src/main/resources/algorithm_schema.xsd +++ b/jsprit-core/src/main/resources/algorithm_schema.xsd @@ -1,14 +1,46 @@ -. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> + + - - - - + + + + + + + + + + + + + + + + + + + @@ -19,7 +51,7 @@ - + @@ -28,9 +60,10 @@ - + + @@ -126,7 +159,7 @@ - + @@ -148,7 +181,7 @@ - + diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/VehicleRoutingAlgorithmTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/VehicleRoutingAlgorithmTest.java index 73ed54f3..d7c3c2f6 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/VehicleRoutingAlgorithmTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/VehicleRoutingAlgorithmTest.java @@ -1,20 +1,18 @@ /******************************************************************************* - * Copyright (c) 2014 Stefan Schroeder. - * + * Copyright (C) 2014 Stefan Schroeder + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either + * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . - * - * Contributors: - * Stefan Schroeder - initial API and implementation ******************************************************************************/ package jsprit.core.algorithm; @@ -38,8 +36,8 @@ public class VehicleRoutingAlgorithmTest { public void whenSettingIterations_itIsSetCorrectly(){ VehicleRoutingAlgorithm algorithm = new VehicleRoutingAlgorithm(mock(VehicleRoutingProblem.class), mock(SearchStrategyManager.class)); - algorithm.setNuOfIterations(50); - assertEquals(50,algorithm.getNuOfIterations()); + algorithm.setMaxIterations(50); + assertEquals(50,algorithm.getMaxIterations()); } @Test @@ -86,7 +84,7 @@ public class VehicleRoutingAlgorithmTest { stratManager); when(stratManager.getRandomStrategy()).thenReturn(mock(SearchStrategy.class)); when(stratManager.getProbabilities()).thenReturn(Arrays.asList(1.0)); - algorithm.setNuOfIterations(1000); + algorithm.setMaxIterations(1000); CountIterations counter = new CountIterations(); algorithm.addListener(counter); algorithm.searchSolutions(); @@ -100,7 +98,7 @@ public class VehicleRoutingAlgorithmTest { stratManager); when(stratManager.getRandomStrategy()).thenReturn(mock(SearchStrategy.class)); when(stratManager.getProbabilities()).thenReturn(Arrays.asList(1.0)); - algorithm.setNuOfIterations(1000); + algorithm.setMaxIterations(1000); PrematureAlgorithmTermination termination = new PrematureAlgorithmTermination() { private int nuOfIterations = 1; @@ -119,4 +117,30 @@ public class VehicleRoutingAlgorithmTest { assertEquals(50,counter.getCountIterations()); } + @Test + public void whenAddingPrematureTermination_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; + } + + }; + CountIterations counter = new CountIterations(); + algorithm.addListener(counter); + algorithm.addTerminationCriterion(termination); + algorithm.searchSolutions(); + assertEquals(50,counter.getCountIterations()); + } + } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/io/TestAlgorithmReader.java b/jsprit-core/src/test/java/jsprit/core/algorithm/io/TestAlgorithmReader.java index 262a01f4..bcd4d4d2 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/io/TestAlgorithmReader.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/io/TestAlgorithmReader.java @@ -1,16 +1,16 @@ /******************************************************************************* - * Copyright (C) 2013 Stefan Schroeder - * + * Copyright (C) 2014 Stefan Schroeder + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either + * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . ******************************************************************************/ @@ -26,6 +26,7 @@ import jsprit.core.algorithm.io.VehicleRoutingAlgorithms.TypedMap.AcceptorKey; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms.TypedMap.RuinStrategyKey; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms.TypedMap.SelectorKey; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms.TypedMap.StrategyModuleKey; +import jsprit.core.algorithm.listener.IterationEndsListener; import jsprit.core.algorithm.listener.SearchStrategyModuleListener; import jsprit.core.algorithm.ruin.RuinStrategy; import jsprit.core.algorithm.ruin.listener.RuinListener; @@ -36,6 +37,7 @@ import jsprit.core.problem.io.VrpXMLReader; import jsprit.core.problem.job.Job; import jsprit.core.problem.solution.VehicleRoutingProblemSolution; import jsprit.core.problem.solution.route.VehicleRoute; +import junit.framework.Assert; import org.apache.commons.configuration.ConfigurationException; import org.junit.Before; import org.junit.Test; @@ -64,6 +66,43 @@ public class TestAlgorithmReader { new VrpXMLReader(vrpBuilder,solutions).read("src/test/resources/finiteVrp.xml"); vrp = vrpBuilder.build(); } + + @Test + public void itShouldReadMaxIterations(){ + VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp,"src/test/resources/algorithmConfigForReaderTest.xml"); + Assert.assertEquals(2000,vra.getMaxIterations()); + } + + static class IterationCounter implements IterationEndsListener { + + int iterations = 0; + + @Override + public void informIterationEnds(int i, VehicleRoutingProblem problem, Collection solutions) { + iterations = i; + } + + } + + @Test + public void whenSettingPrematureBreak_itShouldReadTermination(){ + VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp,"src/test/resources/algorithmConfigForReaderTest2.xml"); + IterationCounter iCounter = new IterationCounter(); + vra.addListener(iCounter); + vra.searchSolutions(); + Assert.assertEquals(100,iCounter.iterations); + } + + @Test + public void itShouldReadTermination(){ + VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp,"src/test/resources/algorithmConfigForReaderTest.xml"); + IterationCounter iCounter = new IterationCounter(); + vra.addListener(iCounter); + vra.searchSolutions(); + Assert.assertEquals(100,iCounter.iterations); + } + + @Test public void testTypedMap(){ diff --git a/jsprit-core/src/test/resources/algorithmConfigForReaderTest.xml b/jsprit-core/src/test/resources/algorithmConfigForReaderTest.xml new file mode 100755 index 00000000..7129aa61 --- /dev/null +++ b/jsprit-core/src/test/resources/algorithmConfigForReaderTest.xml @@ -0,0 +1,70 @@ + + + + + + 2000 + + + + 100 + + + + + + + + + 1 + + + + + + + + 0.5 + + + + + + 0.5 + + + + + + + + + 0.3 + + + + + + 0.5 + + + + + + diff --git a/jsprit-core/src/test/resources/algorithmConfigForReaderTest2.xml b/jsprit-core/src/test/resources/algorithmConfigForReaderTest2.xml new file mode 100755 index 00000000..6decd70f --- /dev/null +++ b/jsprit-core/src/test/resources/algorithmConfigForReaderTest2.xml @@ -0,0 +1,69 @@ + + + + + + 2000 + + + 100 + + + + + + + + + 1 + + + + + + + + 0.5 + + + + + + 0.5 + + + + + + + + + 0.3 + + + + + + 0.5 + + + + + + diff --git a/jsprit-examples/input/algorithmConfigWithSchrimpfAcceptance.xml b/jsprit-examples/input/algorithmConfigWithSchrimpfAcceptance.xml index 620c208b..4e1afd6f 100755 --- a/jsprit-examples/input/algorithmConfigWithSchrimpfAcceptance.xml +++ b/jsprit-examples/input/algorithmConfigWithSchrimpfAcceptance.xml @@ -1,9 +1,39 @@ + + - 2000 + 2000 + + + + + + + 100 + + + 0.1 + 100 + +