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-14 20:09:09 +02:00
parent 89350be1e4
commit c75d3d5cc2
8 changed files with 334 additions and 42 deletions

View file

@ -39,6 +39,25 @@ import java.util.Collection;
*/
public class VehicleRoutingAlgorithm {
private static class TerminationManager implements PrematureAlgorithmTermination {
private Collection<PrematureAlgorithmTermination> terminationCriteria = new ArrayList<PrematureAlgorithmTermination>();
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;

View file

@ -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 <http://www.gnu.org/licenses/>.
******************************************************************************/
@ -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);

View file

@ -1,14 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com"
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ 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
~ 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 <http://www.gnu.org/licenses/>.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com" elementFormDefault="qualified">
<xs:element name="algorithm">
<xs:complexType>
<xs:sequence>
<xs:element name="iterations" type="xs:integer" minOccurs="0" maxOccurs="1" default="100"/>
<xs:element name="prematureBreak" type="prematureBreakType" minOccurs="0" maxOccurs="1"/>
<xs:choice>
<xs:element name="iterations" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="maxIterations" type="xs:integer" minOccurs="0" maxOccurs="1"/>
</xs:choice>
<xs:choice>
<xs:element name="prematureBreak" type="prematureBreakType" minOccurs="0" maxOccurs="1"/>
<xs:element name="terminationCriteria">
<xs:complexType>
<xs:sequence>
<xs:element name="termination" type="prematureBreakType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
<xs:element name="construction" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
@ -19,7 +51,7 @@
<xs:element name="strategy">
<xs:complexType>
<xs:all>
<xs:sequence>
<xs:element name="memory" type="xs:integer" minOccurs="0" maxOccurs="1" default="1"/>
<xs:element name="searchStrategies" minOccurs="1" maxOccurs="1">
<xs:complexType>
@ -28,9 +60,10 @@
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
@ -126,7 +159,7 @@
<xs:sequence>
<xs:element name="threshold" type="xs:double" minOccurs="1" maxOccurs="1"/>
<xs:element name="iterations" type="xs:integer" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:sequence>
</xs:group>
<xs:complexType name="moduleType">
@ -148,7 +181,7 @@
<xs:sequence>
<xs:element name="ruin" type="ruinType"/>
<xs:element name="insertion" type="insertionType"/>
</xs:sequence>
</xs:sequence>
</xs:group>
<xs:group name="gendreau_group">

View file

@ -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 <http://www.gnu.org/licenses/>.
*
* 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());
}
}

View file

@ -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 <http://www.gnu.org/licenses/>.
******************************************************************************/
@ -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<VehicleRoutingProblemSolution> 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(){

View file

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ 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
~ 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 <http://www.gnu.org/licenses/>.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<algorithm xmlns="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com algorithm_schema.xsd">
<maxIterations>2000</maxIterations>
<terminationCriteria>
<termination basedOn="iterations">
<iterations>100</iterations>
</termination>
</terminationCriteria>
<construction>
<insertion name="bestInsertion"/>
</construction>
<strategy>
<memory>1</memory>
<searchStrategies>
<searchStrategy name="randomRuinAndRecreate">
<selector name="selectBest"/>
<acceptor name="acceptNewRemoveWorst"/>
<modules>
<module name="ruin_and_recreate">
<ruin name="randomRuin">
<share>0.5</share>
</ruin>
<insertion name="bestInsertion"/>
</module>
</modules>
<probability>0.5</probability>
</searchStrategy>
<searchStrategy name="radialRuinAndRecreate">
<selector name="selectBest"/>
<acceptor name="acceptNewRemoveWorst"/>
<modules>
<module name="ruin_and_recreate">
<ruin name="radialRuin">
<share>0.3</share>
</ruin>
<insertion name="bestInsertion"/>
</module>
</modules>
<probability>0.5</probability>
</searchStrategy>
</searchStrategies>
</strategy>
</algorithm>

View file

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ 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
~ 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 <http://www.gnu.org/licenses/>.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<algorithm xmlns="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com algorithm_schema.xsd">
<maxIterations>2000</maxIterations>
<prematureBreak basedOn="iterations">
<iterations>100</iterations>
</prematureBreak>
<construction>
<insertion name="bestInsertion"/>
</construction>
<strategy>
<memory>1</memory>
<searchStrategies>
<searchStrategy name="randomRuinAndRecreate">
<selector name="selectBest"/>
<acceptor name="acceptNewRemoveWorst"/>
<modules>
<module name="ruin_and_recreate">
<ruin name="randomRuin">
<share>0.5</share>
</ruin>
<insertion name="bestInsertion"/>
</module>
</modules>
<probability>0.5</probability>
</searchStrategy>
<searchStrategy name="radialRuinAndRecreate">
<selector name="selectBest"/>
<acceptor name="acceptNewRemoveWorst"/>
<modules>
<module name="ruin_and_recreate">
<ruin name="radialRuin">
<share>0.3</share>
</ruin>
<insertion name="bestInsertion"/>
</module>
</modules>
<probability>0.5</probability>
</searchStrategy>
</searchStrategies>
</strategy>
</algorithm>